<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/11/2
 * Time: 17:19
 */

namespace Hrm\Controllers;
use Admin\Frontend\Controllers\ControllerBase;
use Admin\Models\hrm\XhhrmAttend;
use Admin\Models\hrm\XhhrmAttendRecord;
use Admin\Models\hrm\XhhrmDepart;
use Admin\Models\hrm\XhhrmHoliday;
use Admin\Models\hrm\XhhrmStaff;
use function GuzzleHttp\Psr7\str;
use Helpers\Assets;
use Helpers\Hrm;
use Helpers\Main;
use Helpers\Template;
use Helpers\Tool;
use Helpers\User;
use Helpers\XhException;
use Modules\Power;
use Phalcon\Mvc\Dispatcher;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

class AttendanceController extends ControllerBase
{
    public function beforeExecuteRoute(Dispatcher $dispatcher)
    {
//        if (in_array(strtolower($dispatcher->getActionName()), [
//            strtolower('index'),
//            strtolower('getStaff'),
//        ])) {
//            return true;
//        }
        //检查是否已登陆，否则跳转到登陆页面
        if (!User::isLogin()) {
            Main::goLoginPage();
            return false;
        }
        return true;
    }

    public static $enums = [
        'iLateType' => [
            0 => '<div >正常</div>',
            1 => '<div class="grid-cell-text-bg-yellow">迟到</div>',
            2 => '<div class="grid-cell-text-bg-green">严重迟到</div>',
            3 =>'<div class="grid-cell-text-bg-red">上午旷工</div>',
            10 => '<div class="grid-cell-text-bg-red">缺卡</div>',
            4 => '<div class="grid-cell-text-bg-blue">补卡</div>',
            5 => '<div class="grid-cell-text-bg-blue">出差</div>',
            6 => '<div class="grid-cell-text-bg-blue">外勤</div>',
            7 => '<div class="grid-cell-text-bg-blue">请假</div>',
        ],
        'iEarlyType' => [
            0 => '<div >正常</div>',
            1 => '<div class="grid-cell-text-bg-yellow">早退</div>',
            2 => '<div class="grid-cell-text-bg-green">严重早退</div>',
            3 =>'<div class="grid-cell-text-bg-red">下午旷工</div>',
            10 => '<div class="grid-cell-text-bg-red">缺卡</div>',
            4 => '<div class="grid-cell-text-bg-blue">补卡</div>',
            5 => '<div class="grid-cell-text-bg-blue">出差</div>',
            6 => '<div class="grid-cell-text-bg-blue">外勤</div>',
            7 => '<div class="grid-cell-text-bg-blue">请假</div>'
        ],
        'iOffType' => [
            0 => '',
            1 => '丧假',
            2 => '事假',
            3 => '年假',
            4 => '病假',
            5 => '调休',
            6 => '陪产假',
            7 => '婚假',
            8 => '产假',
        ],
    ];

    public static $rules = [
        'moduleOne' => [
            'overWork' => ['21:00', '00:00'],
            'overWeek' => '4',
        ],
        'moduleTwo' => [
            'overWork' => ['21:00', '00:00'],
            'overWeek' => [
                [
                    'in'  => ['00:00', '09:00'],
                    'out' => ['11:30', '17:30', '21:00', '00:00']
                ],
                [
                    'in'  => ['09:00', '13:00'],
                    'out' => ['17:30', '21:00', '00:00']
                ],
                [
                    'in'  => ['13:00', '18:00'],
                    'out' => ['21:00', '00:00']
                ],
                [
                    'in'  => ['18:00', '21:00'],
                    'out' => ['00:00']
                ],
            ],
        ]
    ];

    public static $depTree = [
        [
            'name' => '产品研发部',
            'prefixRange' => ['CY'],
            'depTag' => 'XHCPYFB'
        ],
//        [
//            'name' => '教学部',
//            'prefixRange' => ['ZY','JY'],
//            'depTag' => 'XHJXB',
//        ]
    ];



    /**
     * 人力考勤
     *
     * @return \Phalcon\Mvc\View
     *
     * create by dale  20190218
     */
    public function indexAction()
    {
        if (!Power::exist('Hrm_Attend')) {
            return $this->sendViewError('缺少权限');
        }
        $this->view->pick('attendance/index');
        Assets::easyUI();
        Assets::importJs('js/attendance/index.js');
        return $this->view->setVars([
            'depTree' => self::$depTree ,
        ]);
    }



    /**
     * 导入考勤数据
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181119
     */
    public function importAttendAction()
    {
        try {
            if (!Power::exist('Hrm_Attend_Add')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $moduleType = $this->request->getPost('moduleType', 'string');
            if (!$moduleType) {
                throw new \Exception('没有选择模式');
            }
            $file = $this->request->getUploadedFiles()[0];
            $fileName = md5_file($file->getTempName()) . '.' . $file->getExtension();
            $filePath = TEMP_PATH . '/' . $fileName;
            $file->moveTo($filePath);
            set_time_limit(50);
            ini_set('memory_limit', '500M');
            $dataSource = Tool::readExcelBySheet($filePath, true, 2);
            $recordSuccess = $this->importAttendRecord($dataSource);
            unset($dataSource);
            $dataSource = Tool::readExcelBySheet($filePath, true, 1);
            $detailSuccess  = $this->importAttendDetail($dataSource, $moduleType);
            unset($dataSource);
            return $this->sendSuccessResponse('导入考勤原始记录:'.$recordSuccess.
                '<br/>导入考勤每日统计:'. $detailSuccess);
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }


    /**
     * 导入考勤原始记录
     *
     * @param $dataSource
     *
     * @return string
     *
     * create by dale  20181119
     */
    private function importAttendRecord(&$dataSource)
    {
        try {
            if (!$dataSource) {
                throw new XhException('导入的excel没有数据');
            }
            $convertTitleArr = [
                'sStaffName' => '姓名',
                'sStaffNumber' => '工号',
                'sBaseNumber' => 'UserId',
                'sDay' => '考勤日期',
                'sAttendTime' => '考勤时间',
                'sSignTime' => '打卡时间',
                'sSignStatus' => '打卡结果',
                'sSignAddress' => '打卡地址',
                'sSignDesc' => '打卡备注',
                'sSignDev' => '打卡设备',
                'sAdminDesc' => '管理员修改备注',
            ];
            $convertTitleArr = array_flip($convertTitleArr); //键值对反转
            $dataPeriod = @$dataSource['title'][0];
            if (!$dataPeriod) {
                throw new XhException('没有时段');
            }
            $dataPeriod = explode('：', $dataPeriod);
            $dataPeriod = end($dataPeriod);
            $dataPeriod = explode('至', trim($dataPeriod));
            $startDay = trim(current($dataPeriod));
            $endDay = trim(end($dataPeriod));
            unset($dataPeriod);
            $yearFirst = substr($startDay, 0, 2);
            $data = @$dataSource['data'];
            unset($dataSource);
            if (!$data) {
                throw new XhException('没有数据');
            }
            $indexTitleArr = Tool::getValue($data, 1, []);
            if (!$indexTitleArr) {
                throw new XhException('没有数据');
            }
            $filedIndexArr = []; //字段和index对应关系数组
            foreach ($indexTitleArr as $index => $title) {
                $field = Tool::getValue($convertTitleArr, $title, null);
                if ($field) {
                    $filedIndexArr[$field] = $index;
                }
            }
            unset($convertTitleArr);
            $filedArr = array_flip($filedIndexArr); // index => field  对应数组
            unset($filedIndexArr);
            $data = array_filter(
                $data,
                function ($val) {
                    if ($val[0]) {
                        return true;
                    }
                }
            );
            $needKeys = array_keys($filedArr);
            $baseNumberToStaffNumberArr = $this->getStaffNumber();
            $itemArr = [];
            foreach ($data as $index => $row) {
                if ($index < 2) {
                    continue;
                }
                $arr = [];
                foreach ($row as $key => $value) {
                    if (in_array($key, $needKeys)) {
                        $arr[$filedArr[$key]] = $value;
                    }
                }
                if (!$arr['sDay']) {
                    continue;
                }
                if (!$arr['sStaffNumber'] && $arr['sBaseNumber']) {
                    $arr['sStaffNumber'] = $arr['sBaseNumber'];
                }
                if (strlen($arr['sStaffNumber']) != 7 && $baseNumberToStaffNumberArr) { //尝试修复staffNumber
                    $arr['sStaffNumber'] = Tool::getValue(
                        $baseNumberToStaffNumberArr,
                        $arr['sBaseNumber'],
                        $arr['sBaseNumber']
                    );
                }
//                unset($arr['sBaseNumber']);
                $tempDate = $yearFirst . $arr['sDay'];
                $tempDate = explode(' ', $tempDate);
                $arr['sDay'] = @$tempDate[0];
                $arr['sWeek'] = @$tempDate[1];
                unset($tempDate);
                if (!$arr['sDay'] || !$arr['sWeek']) {
                    continue;
                }
                $itemArr[$arr['sStaffNumber']][] = $arr;
                unset($arr);
                unset($row[$index]);
            }
            unset($data);
            $totalNum = count($itemArr);
            $errorNum = 0;
            $successNum = 0;
            foreach ($itemArr as $index => $rows) {
                $baseNumber = @$rows[0]['sBaseNumber'];
                $sql = "delete from XHHrm_AttendRecord where  sDay >= '{$startDay}' and sDay <= '{$endDay}'
                and sBaseNumber = '{$baseNumber}' ";
                $result = $this->db->execute($sql);
                if (!$result) {
                    $errorNum++;
                    continue;
                }
                $keys = array_keys(reset($rows));
                $keys = array_map(function ($key) {
                    return "`{$key}`";
                }, $keys);
                $keys = implode(',', $keys);
                $sql = "INSERT INTO  XHHrm_AttendRecord ({$keys}) VALUES ";
                foreach ($rows as $v) {
                    $v = array_map(function ($value) {
                        return "'{$value}'";
                    }, $v);
                    $values = implode(',', array_values($v));
                    $sql .= " ({$values}), ";
                }
                $sql = rtrim(trim($sql), ',');
                $res = $this->db->execute($sql);
                if (!$res) {
                    unset($rows[$index]);
                    $errorNum++;
                }
                $successNum++;
                unset($rows[$index]);
            }
            unset($data);
            return "共执行{$totalNum}次,成功{$successNum}次,失败{$errorNum}次。";
        } catch (\Exception $e) {
            return $e->getMessage();
        }
    }

    /**
     * 获取staffNumber
     *
     * @return array
     *
     * create by dale  20181220
     */
    private function getStaffNumber()
    {
        $sql = "select sStaffNumber,sBaseNumber from  XHHrm_Attend 
                  where bDelete= 0 GROUP BY sBaseNumber order by sDay desc ";
        $enum = $this->db->fetchAll($sql);
        if (!$enum) {
            return [];
        }
        return array_column($enum, 'sStaffNumber', 'sBaseNumber');
    }

    /**
     * 获取一个时间段内的假期
     *
     * @param $startDay
     * @param $endDay
     *
     * @return array
     * @throws XhException
     *
     * create by dale  20181126
     */
    public function getPeriodsHoliday($startDay, $endDay)
    {
        if (!$startDay || !$endDay) {
            throw new XhException('缺少参数');
        }
        if ($startDay > $endDay) {
            throw new XhException('开始时间大于结束时间');
        }
        $holidayArr = [];
        $setArr = XhhrmHoliday::find([
            'conditions' => 'bDelete= 0 and sDay >= :startDay: and sDay <= :endDay:',
            'bind'       => ['startDay' => $startDay, 'endDay' => $endDay],
        ])->toArray();
        if ($setArr) {
            $setArr = array_column($setArr, null, 'sDay');
        }
        for ($day = $startDay; $day <= $endDay; $day = date('Y-m-d', strtotime("$day +1 day"))) {
            $setDay = Tool::getValue($setArr, $day);
            if ($setDay) {
                if ($setDay['bHoliday']) {
                    $holidayArr[] = $day;
                }

            } else {
                $w = date('w', strtotime($day)) + 1;
                if (in_array($w, [1, 7])) {
                    $holidayArr[] = $day;
                }
            }
        }
        return $holidayArr;
    }


//    private function importAttendRecord(&$dataSource)
//    {
//        try {
//            if (!$dataSource) {
//                throw new XhException('导入的excel没有数据');
//            }
//            $convertTitleArr = [
//                'sStaffName' => '姓名',
//                'sStaffNumber' => 'UserId',
//                'sDay' => '考勤日期',
//                'sAttendTime' => '考勤时间',
//                'sSignTime' => '打卡时间',
//                'sSignStatus' => '打卡结果',
//                'sSignAddress' => '打卡地址',
//                'sSignDesc' => '打卡备注',
//                'sSignDev' => '打卡设备',
//                'sAdminDesc' => '管理员修改备注',
//            ];
//            $convertTitleArr = array_flip($convertTitleArr); //键值对反转
//            $dataPeriod = @$dataSource['title'][0];
//            if (!$dataPeriod) {
//                throw new XhException('没有时段');
//            }
//            $dataPeriod = explode('：', $dataPeriod);
//            $dataPeriod = end($dataPeriod);
//            $dataPeriod = explode('至', trim($dataPeriod));
//            $startDay = trim(current($dataPeriod));
//            unset($dataPeriod);
//            $yearFirst = substr($startDay, 0, 2);
//            $data = @$dataSource['data'];
//            unset($dataSource);
//            if (!$data) {
//                throw new XhException('没有数据');
//            }
//            $indexTitleArr = Tool::getValue($data, 1, []);
//            if (!$indexTitleArr) {
//                throw new XhException('没有数据');
//            }
//            $filedIndexArr = []; //字段和index对应关系数组
//            foreach ($indexTitleArr as $index => $title) {
//                $field = Tool::getValue($convertTitleArr, $title, null);
//                if ($field) {
//                    $filedIndexArr[$field] = $index;
//                }
//            }
//            unset($convertTitleArr);
//            $filedArr = array_flip($filedIndexArr); // index => field  对应数组
//            unset($filedIndexArr);
//            $data = array_filter(
//                $data,
//                function ($val) {
//                    if ($val[0]) {
//                        return true;
//                    }
//                }
//            );
//            $totalNum = count($data) - 2;
//            $errorNum = 0;
//            $successNum = 0;
//            $skipNum = 0;
//            $needKeys = array_keys($filedArr);
//            foreach ($data as $index => $row) {
//                if ($index < 2) {
//                    continue;
//                }
//                $arr = [];
//                foreach ($row as $key => $item) {
//                    if (in_array($key, $needKeys)) {
//                        $arr[$filedArr[$key]] = $item;
//                    }
//                }
//                if (!$arr['sDay']) {
//                    $skipNum++;
//                    continue;
//                }
//                $tempDate = $yearFirst . $arr['sDay'];
//                $tempDate = explode(' ', $tempDate);
//                $arr['sDay'] = @$tempDate[0];
//                $arr['sWeek'] = @$tempDate[1];
//                if (!$arr['sDay'] || !$arr['sWeek']) {
//                    $errorNum++;
//                    continue;
//                }
//                $check = XhhrmAttendRecord::findFirst([
//                    'conditions' => 'sStaffNumber = :sStaffNumber: and bDelete = 0 and sSignTime = :sSignTime:
//                        and sSignStatus = :sSignStatus: and sAttendTime = :sAttendTime: ',
//                    'bind'       =>  ['sStaffNumber' => $arr['sStaffNumber'], 'sSignTime' => $arr['sSignTime'],
//                        'sSignStatus' => $arr['sSignStatus'], 'sAttendTime' => $arr['sAttendTime']]
//                ]);
//                if ($check) {
//                    $skipNum++;
//                    unset($check);
//                    continue;
//                }
//                $obj = new XhhrmAttendRecord();
//                $obj->assign($arr);
//                if (!$obj->save()) {
//                    $errorNum++;
//                    unset($obj);
//                    continue;
//                }
//                unset($obj);
//                unset($data[$index]);
//                $successNum++;
//            }
//            unset($data);
//            return "共执行{$totalNum}次,成功{$successNum}次,跳过{$skipNum}次,失败{$errorNum}次。";
//        } catch (\Exception $e) {
//            return $e->getMessage();
//        }
//    }

    /**
     * 导入每日考勤明细
     *
     * @param $dataSource
     *
     * @return string
     *
     * create by dale  20181119
     * modify by dale 20181210  添加不在考勤组不做任何处理
     */
    private function importAttendDetail(&$dataSource, $moduleType)
    {
        try {
            if (!$dataSource) {
                throw new XhException('导入的excel没有数据');
            }
            $convertTitleArr = [
                'sStaffName' => '姓名',
                'sStaffNumber' => '工号',
                'sBaseNumber' => 'UserId',
                'sDay' => '日期',
                'signStatus' => '班次',
                'sSignIn' => '上班1',
                'sSignOut' => '下班1',
                'sCheckInfo' => '关联的审批单',
//                'bHoliday' => '休息天数',
                'weekStart' => '请假',
                'weekEnd' => '加班-审批单统计'
            ];
            $convertTitleArr = array_flip($convertTitleArr); //键值对反转
            $dataPeriod = @$dataSource['title'][0];
            if (!$dataPeriod) {
                throw new XhException('没有时段');
            }
            $dataPeriod = explode('：', $dataPeriod);
            $dataPeriod = end($dataPeriod);
            $dataPeriod = explode('至', trim($dataPeriod));
            $startDay = trim(current($dataPeriod));
            $endDay = trim(end($dataPeriod));
            unset($dataPeriod);
            $yearFirst = substr($startDay, 0, 2);
            $data = @$dataSource['data'];
            unset($dataSource);
            if (!$data) {
                throw new XhException('没有数据');
            }
            $indexTitleArr = Tool::getValue($data, 1, []);
            if (!$indexTitleArr) {
                throw new XhException('没有数据');
            }
            $filedIndexArr = []; //字段和index对应关系数组
            foreach ($indexTitleArr as $index => $title) {
                $field = Tool::getValue($convertTitleArr, $title, null);
                if ($field) {
                    $filedIndexArr[$field] = $index;
                }
            }
            unset($convertTitleArr);
            $filedArr = [];
            $weekStart = 0;
            $weekEnd = 0;
            $titleWeekArr = Tool::getValue($data, 2, []);
            foreach ($filedIndexArr as $field => $index) {
                $filedArr[$index] = $field;
                if ($field == 'sSignIn') {
                    $filedArr[$index + 1] = 'sInStatus';
                }
                if ($field == 'sSignOut') {
                    $filedArr[$index + 1] = 'sOutStatus';
                }
                if ($field == 'weekStart') {
                    $weekStart = $index;
                }
                if ($field == 'weekEnd') {
                    $weekEnd = $index - 1;
                }
            }
            $data = array_filter(
                $data,
                function ($val) {
                    if ($val[0]) {
                        return true;
                    }
                }
            );
            $needKeys = array_keys($filedArr);
            $holidays = $this->getPeriodsHoliday($startDay, $endDay);
            $baseNumberToStaffNumberArr = $this->getStaffNumber();
            $itemArr = [];
            foreach ($data as $index => $row) {
                if ($index < 3) {
                    continue;
                }
                $item = [
                    'sStaffName' => '',
                    'sStaffNumber' => '',
                    'sBaseNumber' => '',
                    'sDay' => '',
                    'sWeek' => '',
                    'sSignIn' => '',
                    'sSignOut' => '',
                    'sCheckInfo' => '',
                    'iLateType' => 0,
                    'iEarlyType' => 0,
                    'dOverTime' => 0,
                    'iMeal' => 0,
                    'iFixSign' => 0,
                    'dOverWeek' => 0,
                    'dAbsent' => 0,
                    'dOffDay' => 0,
                    'bHoliday' => 0,
                    'iOffType' => 0,
                    'bInAttend' => 0,
                    'dWorkHour' => 0,
                    'dOverHour' => 0,
                    'bUnusual'  => 0,
                    'sAttendRule' => $moduleType,
                ];
                $arr = [];
                foreach ($row as $key => $value) {
                    if (in_array($key, $needKeys)) {
                        $arr[$filedArr[$key]] = $value;
                    }
                }
                if (!$arr['sStaffNumber'] && $arr['sBaseNumber']) {
                    $arr['sStaffNumber'] = $arr['sBaseNumber'];
                }

                if (strlen($arr['sStaffNumber']) != 7 && $baseNumberToStaffNumberArr) { //尝试修复staffNumber
                    $arr['sStaffNumber'] = Tool::getValue(
                        $baseNumberToStaffNumberArr,
                        $arr['sBaseNumber'],
                        $arr['sBaseNumber']
                    );
                }
                $tempDate = $yearFirst . $arr['sDay'];
                $tempDate = explode(' ', $tempDate);
                $arr['sDay'] = @$tempDate[0];
                $arr['sWeek'] = @$tempDate[1];
                if (!$arr['sDay'] || !$arr['sWeek']) {
                    continue;
                }
                $arr['bInAttend'] = 0;
                if ($arr['signStatus']) {
                    if (strpos($arr['signStatus'], '不在考勤组') === false) { //不是不在考勤组
                        $arr['bInAttend'] = 1;
                    }
                }
                if ($arr['sSignIn']) {
                    $arr['sSignIn'] = $arr['sDay'].' '.$arr['sSignIn'];
                }
                $arr['bHoliday'] = in_array($arr['sDay'], $holidays) ? 1 : 0;
                if (strpos($arr['sSignOut'], '次日') !== false) {
                    $tomorrow = date('Y-m-d', strtotime("{$arr['sDay']} +1 day"));
                    $arr['sSignOut'] = str_replace('次日', $tomorrow, $arr['sSignOut']);
                } else {
                    if ($arr['sSignOut']) {
                        $arr['sSignOut'] = $arr['sDay'].' '.$arr['sSignOut'];
                    }
                }
                $fixArr = $this->fixLateEarlyType($arr['sSignIn'], $arr['sSignOut'], $arr['bHoliday']);
                if ($fixArr) {
                    $arr = array_merge($arr, $fixArr);
                }
                if ($arr['bInAttend']) {
                    $arr['iLateType'] = $this->getLateType($arr['sInStatus'], $arr['sDay'], $arr['sSignIn']);
                    $arr['iEarlyType'] = $this->getEarlyType($arr['sOutStatus'], $arr['sDay'], $arr['sSignOut']);
                    if ($arr['iEarlyType'] == 7 && $arr['iLateType'] != 7 && !$arr['sSignOut']) { //下午请假未打卡
                        $arr['bUnusual'] = 1;
                    }
                } else {
                    $arr['iLateType'] = 0;
                    $arr['iEarlyType'] = 0;
                }

//                if ($arr['iEarlyType'] == 1) {
//                    $arr['iEarlyType'] = $this->fixEarlyType($arr['sDay'], $arr['sSignOut']);
//                }
                $specialArr = $this->getSpecialArr($arr['iLateType'], $arr['iEarlyType']);
                $arr['iOffType'] = $this->getWeekType($weekStart, $weekEnd, $titleWeekArr, $row);
                if ($specialArr) {
                    $arr = array_merge($arr, $specialArr);
                }
                $overArr = $this->calculateOverTime(
                    $arr['sDay'],
                    $arr['sSignIn'],
                    $arr['sSignOut'],
                    $arr['bHoliday'],
                    $arr['sCheckInfo'],
                    $moduleType
                );
                $arr = array_merge($arr, $overArr);
                $itemKeys = array_keys($item);
                foreach ($arr as $key => $value) {
                    if (in_array($key, $itemKeys)) {
                        $item[$key] = $value;
                    }
                }
                unset($arr);
                unset($data[$index]);
                $itemArr[$item['sStaffNumber']][] = $item;
            }
            unset($data);
            $totalNum = count($itemArr);
            $errorNum = 0;
            $successNum = 0;
            foreach ($itemArr as $index => $rows) {
                $baseNumber = @$rows[0]['sBaseNumber'];
                $sql = "delete from XHHrm_Attend  where sDay >= '{$startDay}' and sDay <= '{$endDay}'
                      and sBaseNumber = '{$baseNumber}' ";
                $result = $this->db->execute($sql);
                unset($sql);
                if (!$result) {
                    $errorNum++;
                    continue;
//                    throw new \Exception("{$startDay}至{$endDay}考勤记录删除失败");
                }
                $keys = array_keys(reset($rows));
                $keys = array_map(function ($key) {
                    return "`{$key}`";
                }, $keys);
                $keys = implode(',', $keys);
                $sql = "INSERT INTO  XHHrm_Attend ({$keys}) VALUES ";
                foreach ($rows as $v) {
                    $v = array_map(function ($value) {
                        return "'{$value}'";
                    }, $v);
                    $values = implode(',', array_values($v));
                    $sql .= " ({$values}), ";
                }
                $sql = rtrim(trim($sql), ',');
                $res = $this->db->execute($sql);
                if (!$res) {
                    unset($rows[$index]);
                    $errorNum++;
                }
                $successNum++;
                unset($rows[$index]);
            }
            return "共执行{$totalNum}次,成功{$successNum}次,失败{$errorNum}次。";
        } catch (\Exception $e) {
            return $e->getMessage();
        }
    }

    /**
     * 获取specialArr
     *
     * @param $iLateType
     * @param $iEarlyType
     *
     * @return array
     *
     * create by dale  20181120
     */
    public function getSpecialArr($iLateType, $iEarlyType)
    {
        $arr = [];
        if (in_array($iLateType, [3, 10]) || in_array($iEarlyType, [3, 10])) {  //可能存在两个都旷工
            $arr['dAbsent'] = 0.5;
        }
        if (in_array($iLateType, [3, 10]) && in_array($iEarlyType, [3, 10])) { //两个都旷工 记未旷工1天
            $arr['dAbsent'] = 1;
        }
        if ($iLateType == 7 || $iEarlyType == 7) {
            $arr['dOffDay'] = 0.5;
        }
        if ($iLateType == 7 && $iEarlyType == 7) {
            $arr['dOffDay'] = 1;
        }
        if ($iLateType == 4 || $iEarlyType == 4) {  //可能存在两个都补卡
            $arr['iFixSign'] = 1;
        }
        if ($iLateType == 4 && $iEarlyType == 4) { //两个都都补卡
            $arr['iFixSign'] = 2;
        }
        return $arr;
    }


//    private function importAttendDetail(&$dataSource)
//    {
//        try {
//            if (!$dataSource) {
//                throw new XhException('导入的excel没有数据');
//            }
//            $convertTitleArr = [
//                'sStaffName' => '姓名',
//                'sStaffNumber' => 'UserId',
//                'sDay' => '日期',
//                'signStatus' => '班次',
//                'sSignIn' => '上班1',
//                'sSignOut' => '下班1',
//                'bHoliday' => '休息天数',
//                'iLoseWeek' => '请假',
//            ];
//            $convertTitleArr = array_flip($convertTitleArr); //键值对反转
//            $dataPeriod = @$dataSource['title'][0];
//            if (!$dataPeriod) {
//                throw new XhException('没有时段');
//            }
//            $dataPeriod = explode('：', $dataPeriod);
//            $dataPeriod = end($dataPeriod);
//            $dataPeriod = explode('至', trim($dataPeriod));
//            $startDay = trim(current($dataPeriod));
////            $endDay = trim(end($dataPeriod));
//            unset($dataPeriod);
//            $yearFirst = substr($startDay, 0, 2);
//            $data = @$dataSource['data'];
//            unset($dataSource);
//            if (!$data) {
//                throw new XhException('没有数据');
//            }
//            $indexTitleArr = Tool::getValue($data, 1, []);
//            if (!$indexTitleArr) {
//                throw new XhException('没有数据');
//            }
//            $filedIndexArr = []; //字段和index对应关系数组
//            foreach ($indexTitleArr as $index => $title) {
//                $field = Tool::getValue($convertTitleArr, $title, null);
//                if ($field) {
//                    $filedIndexArr[$field] = $index;
//                }
//            }
//            unset($convertTitleArr);
//            $filedArr = [];
//            foreach ($filedIndexArr as $field => $index) {
//                $filedArr[$index] = $field;
//                if ($field == 'sSignIn') {
//                    $filedArr[$index + 1] = 'sInStatus';
//                }
//                if ($field == 'sSignOut') {
//                    $filedArr[$index + 1] = 'sOutStatus';
//                }
//                if ($field == 'iLoseWeek') {
//                    $filedArr[$index + 1] = 'iThingWeek';
//                    $filedArr[$index + 2] = 'iYearWeek';
//                    $filedArr[$index + 3] = 'iSickWeek1';
//                    $filedArr[$index + 4] = 'iSickWeek2';
//                    $filedArr[$index + 5] = 'iOffWeek';
//                    $filedArr[$index + 6] = 'iBabyWeek';
//                }
//            }
//            $data = array_filter(
//                $data,
//                function ($val) {
//                    if ($val[0]) {
//                        return true;
//                    }
//                }
//            );
//            $totalNum = count($data) - 2;
//            $errorNum = 0;
//            $successNum = 0;
//            $skipNum = 0;
//            $needKeys = array_keys($filedArr);
//            foreach ($data as $index => $row) {
//                if ($index < 3) {
//                    continue;
//                }
//                $arr = [];
//                foreach ($row as $key => $item) {
//                    if (in_array($key, $needKeys)) {
//                        $arr[$filedArr[$key]] = $item;
//                    }
//                }
//                $tempDate = $yearFirst . $arr['sDay'];
//                $tempDate = explode(' ', $tempDate);
//                $arr['sDay'] = @$tempDate[0];
//                $arr['sWeek'] = @$tempDate[1];
//                if (!$arr['sDay'] || !$arr['sWeek']) {
//                    $skipNum++;
//                    continue;
//                }
//                $obj = XhhrmAttend::findFirst([
//                    'conditions' => 'bDelete = 0 and sDay = :sDay: and sStaffNumber = :sStaffNumber:',
//                    'bind'       => ['sDay' => $arr['sDay'], 'sStaffNumber' => $arr['sStaffNumber']]
//                ]);
//                if (!$obj) {
//                    $obj = new XhhrmAttend();
//                } else {
//                    $obj->assign($this->clearAttendData());
//                }
//                if ($arr['signStatus']) {
//                    if (strpos($arr['signStatus'], '不在考勤组')!== false) { //考勤组
//                        $obj->bInAttend = 0;
//                    } else {
//                        $obj->bInAttend = 1;
//                    }
//                }
//                if ($arr['sSignIn']) {
//                    $arr['sSignIn'] = $arr['sDay'].' '.$arr['sSignIn'];
//                }
//                if (strpos($arr['sSignOut'], '次日') !== false) {
//                    $tomorrow = date('Y-m-d', strtotime("{$arr['sDay']} +1 day"));
//                    $arr['sSignOut'] = str_replace('次日', $tomorrow, $arr['sSignOut']);
//                } else {
//                    if ($arr['sSignOut']) {
//                        $arr['sSignOut'] = $arr['sDay'].' '.$arr['sSignOut'];
//                    }
//                }
//                $obj->assign($arr);
//                $fixArr = $this->fixLateEarlyType($obj->sSignIn, $obj->sSignOut, $arr['bHoliday']);
//                if ($fixArr) {
//                    $obj->assign($fixArr);
//                }
//                $obj->iLateType  = $this->getLateType($arr['sInStatus'])['iLateType'];
//                $obj->iEarlyType = $this->getEarlyType($arr['sOutStatus'])['iEarlyType'];
//                if ($obj->iLateType == 3 || $obj->iEarlyType == 3) {  //可能存在两个都旷工
//                    $obj->dAbsent = 0.5;
//                }
//                if ($obj->iLateType == 3 && $obj->iEarlyType == 3) { //两个都旷工 记未旷工1天
//                    $obj->dAbsent = 1;
//                }
//                if ($obj->iLateType == 7 || $obj->iEarlyType == 7) {
//                    $obj->dOffDay = 0.5;
//                    $obj->iOffType = $this->getWeekType($arr);
//                }
//                if ($obj->iLateType == 7 && $obj->iEarlyType == 7) {
//                    $obj->dOffDay = 1;
//                }
//                if ($obj->iLateType == 4 || $obj->iEarlyType == 4) {  //可能存在两个都补卡
//                    $obj->iFixSign = 1;
//                }
//                if ($obj->iLateType == 4 && $obj->iEarlyType == 4) { //两个都都补卡
//                    $obj->iFixSign = 2;
//                }
//                $overArr = $this->calculateOverTime($arr['sDay'], $obj->sSignIn, $obj->sSignOut, $arr['bHoliday']);
//                $obj->assign($overArr);
//                if (!$obj->save()) {
//                    $errorNum++;
//                    unset($obj);
//                    continue;
//                }
//                unset($data);
//                $successNum++;
//            }
//            return "共执行{$totalNum}次,成功{$successNum}次,跳过{$skipNum}次,失败{$errorNum}次。";
//        } catch (\Exception $e) {
//            return $e->getMessage();
//        }
//    }




//    /**
//     * 导入职工考勤记录
//     *
//     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
//     *
//     * create by dale  20181115
//     */
//    public function importStaffAttendRecordAction()
//    {
//        try {
//            $file = $this->request->getUploadedFiles()[0];
//            $fileName = md5_file($file->getTempName()) . '.' . $file->getExtension();
//            $filePath = TEMP_PATH . '/' . $fileName;
//            $file->moveTo($filePath);
//            $dataSource = Tool::readExcelBySheet($filePath, true, 3);
//            if (!$dataSource) {
//                return $this->sendErrorResponse(500, '导入的excel没有数据');
//            }
//            $convertTitleArr = [
//                'sStaffName' => '姓名',
//                'sStaffNumber' => '工号',
//                'sDay' => '考勤日期',
//                'sAttendTime' => '考勤时间',
//                'sSignTime' => '打卡时间',
//                'sSignStatus' => '打卡结果',
//                'sSignAddress' => '打卡地址',
//                'sSignDesc' => '打卡备注',
//                'sSignDev' => '打卡设备',
//                'sAdminDesc' => '管理员修改备注',
//            ];
//            $convertTitleArr = array_flip($convertTitleArr); //键值对反转
//            $dataPeriod = @$dataSource['title'][0];
//            if (!$dataPeriod) {
//                return $this->sendErrorResponse(500, '没有时段');
//            }
//            $dataPeriod = explode('：', $dataPeriod);
//            $dataPeriod = end($dataPeriod);
//            $dataPeriod = explode('至', trim($dataPeriod));
//            $startDay = trim(current($dataPeriod));
////            $endDay = trim(end($dataPeriod));
//            $yearFirst = substr($startDay, 0, 2);
//            $data = @$dataSource['data'];
//            if (!$data) {
//                return $this->sendErrorResponse(500, '没有数据');
//            }
//            $indexTitleArr = Tool::getValue($data, 1, []);
//            if (!$indexTitleArr) {
//                return $this->sendErrorResponse(500, '没有数据');
//            }
//            $filedIndexArr = []; //字段和index对应关系数组
//            foreach ($indexTitleArr as $index => $title) {
//                $field = Tool::getValue($convertTitleArr, $title, null);
//                if ($field) {
//                    $filedIndexArr[$field] = $index;
//                }
//            }
//            $filedArr = array_flip($filedIndexArr); // index => field  对应数组
//            $data = array_filter(
//                $data,
//                function ($val) {
//                    if ($val[0]) {
//                        return true;
//                    }
//                }
//            );
//            $totalNum = count($data) - 2;
//            $errorNum = 0;
//            $successNum = 0;
//            $skipNum = 0;
//            $needKeys = array_keys($filedArr);
//            foreach ($data as $index => $row) {
//                if ($index < 2) {
//                    continue;
//                }
//                $arr = [];
//                foreach ($row as $key => $item) {
//                    if (in_array($key, $needKeys)) {
//                        $arr[$filedArr[$key]] = $item;
//                    }
//                }
//                $tempDate = $yearFirst . $arr['sDay'];
//                $tempDate = explode(' ', $tempDate);
//                $arr['sDay'] = @$tempDate[0];
//                $arr['sWeek'] = @$tempDate[1];
//                if (!$arr['sDay'] || !$arr['sWeek']) {
//                    $errorNum++;
//                    continue;
//                }
//                $check = XhhrmAttendRecord::findFirst([
//                    'conditions' => 'sStaffNumber = :sStaffNumber: and bDelete = 0 and sSignTime = :sSignTime:
//                        and sSignStatus = :sSignStatus: and sAttendTime = :sAttendTime: ',
//                    'bind'       =>  ['sStaffNumber' => $arr['sStaffNumber'], 'sSignTime' => $arr['sSignTime'],
//                        'sSignStatus' => $arr['sSignStatus'], 'sAttendTime' => $arr['sAttendTime']]
//                ]);
//                if ($check) {
//                    $skipNum++;
//                    continue;
//                }
//                $obj = new XhhrmAttendRecord();
//                $obj->assign($arr);
//                if (!$obj->save()) {
//                    $errorNum++;
//                    continue;
//                }
//                $successNum++;
//            }
//            return $this->sendSuccessResponse("共执行{$totalNum}次,成功{$successNum}次,跳过{$skipNum}次,失败{$errorNum}次。");
//        } catch (\Exception $e) {
//            return $this->sendErrorResponse(
//                500,
//                $e->getMessage(),
//                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
//            );
//        }
//    }

    /**
     * 考勤原始记录表
     *
     * @return \Phalcon\Mvc\View
     *
     * create by dale  20181115
     */
    public function recordListAction()
    {
        try {
            if (!Power::exist('Hrm_Attend')) {
                return $this->sendViewError('缺少权限');
            }
            Assets::easyUI();
            $this->view->setTemplateBefore('listForm');
            Assets::importJs('js/attendance/recordList.js');
            $this->view->pick('attendance/recordList');
            Template::exists('Attend_Record', 'list') or die(Main::showMessageModal('配置文件不存在，请先创建！', 109106002));
            $listButtonArr = $formButtonArr = $listSearchArr = array();
//            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_importRec', 'text' => '导入',
//                'icon' => 'fa-plus');
//            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_generate', 'text' => '生成每日考勤',
//                'icon' => 'fa-plus');
            $listSearchArr[] = array('type' => 'text', 'class'  => 'easyui-datebox', 'id' => 'List_Search_StartTime',
                'label' => ' 时间段：','style'=>'width:100px;');
            $listSearchArr[] = array('type' => 'text', 'class' => 'easyui-datebox', 'id' => 'List_Search_EndTime',
                'label' => ' ~ ', 'style' => 'width:100px;');
            $listSearchArr[] = array('type' => 'text', 'id' => 'list_search', 'label' => ' 搜索： ');
            $listSearchArr[] = array('type' => 'button', 'id' => 'bt_list_search', 'text' => '查找',
                'icon' => 'fa-search', 'style' => 'margin-left:10px');
            return $this->view->setVars(array(
                'List' => Template::createList('recList', 'Attend_Record', [
                    'searchToolbar' => Template::createSearchToolBar($listSearchArr, !!$listButtonArr),
                    'buttonToolbar' => Template::createButtonToolBar($listButtonArr),
                ]),
            ));
        } catch (\Exception $e) {
            return $this->sendViewError(
                $e->getMessage()
            );
        }
    }

    /**
     * 生成表单
     *
     * @return string
     *
     * create by dale  20181116
     */
//    public function generateFormAction()
//    {
//        try {
//            $this->view->pick('attendance/generateForm');
//            Assets::importJs('js/attendance/generateForm.js');
//            return $this->view->setVars([
//                'depArr' => XhhrmDepart::getDepEnum()
//            ]);
//        } catch (\Exception $e) {
//            return $this->sendViewError(
//                $e->getMessage()
//            );
//        }
//    }

    /**
     * 获取记录信息
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181115
     */
    public function getRecordAction()
    {
        try {
            $key         = $this->request->getPost('key', 'string');
            $startTime   = $this->request->getPost('startTime', 'string');
            $endTime     = $this->request->getPost('endTime', 'string');
            $staffNumber = $this->request->getPost('staffNumber', 'string');
            $currentDay  = $this->request->getPost('currentDay', 'string');
            $recordColumns =  array_keys(get_object_vars(new XhhrmAttendRecord()));
            $recordColumns = array_map(function ($val) {
                return 'r.' . $val;
            }, $recordColumns);
            $builder = $this->modelsManager->createBuilder()
                ->from(['r' => 'Admin\Models\hrm\XhhrmAttendRecord'])
                ->columns(array_merge($recordColumns))
                ->where('r.bDelete = 0');
            if ($startTime) {
                $builder->andWhere('r.sDay >= :startTime:', ['startTime' => $startTime]);
            }
            if ($endTime) {
                $builder->andWhere('r.sDay <= :endTime:', ['endTime' => $endTime]);
            }
            if ($key) {
                $builder->andWhere('r.sStaffName like :key:', ['key' => '%'.$key.'%']);
            }
            if ($staffNumber) {
                $builder->andWhere('r.sStaffNumber = :sStaffNumber:', ['sStaffNumber' => $staffNumber]);
            }
            if ($currentDay) {
                $builder->andWhere('r.sDay = :sDay:', ['sDay' => $currentDay]);
            }
            $data = Main::runBuilderPage($builder);
            foreach ($data['rows'] as &$row) {
                $row['sWeek'] = "{$row['sDay']} ({$row['sWeek']})";
            }
            unset($row);
            return $this->sendJsonResponse($data);
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 修改用户考勤时间
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181122
     */
    public function setUserAttendTimeAction()
    {
        try {
            $id = $this->request->getPost('id', 'string');
            $signType = $this->request->getPost('signType', 'string');
            $day =$this->request->getPost('day', 'string');
            if (!$id || !$signType || !$day) {
                return $this->sendErrorResponse(400, '缺少参数');
            }
            $record = XhhrmAttendRecord::findFirst($id);
            if (!$record) {
                return $this->sendErrorResponse(500, '未找到考勤记录');
            }
            $record = $record->toArray();
            $diffTime = abs(strtotime($record['sDay']) - strtotime($day));
            if ($diffTime > 24*3600) {
                return $this->sendErrorResponse(500, '设置的时间超过1天无法设置');
            }
            $obj = XhhrmAttend::findFirst([
                'conditions' => 'bDelete = 0 and sStaffNumber = :sStaffNumber: and sDay = :sDay:',
                'bind'       => ['sStaffNumber' => $record['sStaffNumber'],'sDay' => $day]
            ]);
            if (!$obj) {
                return $this->sendErrorResponse(500, '未找到当天的考勤记录');
            }
            if ($signType == 1) { //修改上午
                $obj->sSignIn = $record['sSignTime'];
                $obj->iLateType = $this->getLateType($record['sSignStatus'], $obj->sDay, $record['sSignTime']);
            } elseif ($signType == 2) { //修改下午
                $obj->sSignOut = $record['sSignTime'];
                $obj->iEarlyType = $this->getEarlyType($record['sSignStatus'], $obj->sDay, $record['sSignTime']);
            }
            $obj->assign([ //清除需要设置默认值的属性
                'dAbsent' =>  0,
                'dOverTime' => 0,
                'dOverWeek' => 0,
                'dOffDay' => 0,
                'iMeal' => 0,
                'iFixSign' => 0
            ]);
            $specialArr = $this->getSpecialArr($obj->iLateType, $obj->iEarlyType);
            if ($specialArr) {
                $obj->assign($specialArr);
            }
            $overArr = $this->calculateOverTime(
                $obj->sDay,
                $obj->sSignIn,
                $obj->sSignOut,
                $obj->bHoliday,
                $obj->sCheckInfo
            );
            $obj->assign($overArr);
            if (!$obj->save()) {
                return $this->sendErrorResponse(500, '保存失败');
            }
            return $this->sendSuccessResponse('设置成功');
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

//    /**
//     * 生成用户每日考勤(一段时间)
//     *
//     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
//     *
//     * create by dale  20181116
//     */
//    public function runUserAttendAction()
//    {
//        try {
//            $staffName = $this->request->getPost('staffName', 'string', '陈凯');
//            $staffNumber = $this->request->getPost('staffNumber', 'string', 'xh00010');
//            $startTime = $this->request->getPost('startTime', 'string', '2018-09-02');
//            $endTime   = $this->request->getPost('endTime', 'string', '2018-09-10');
//            if (!$startTime || !$endTime || !$staffNumber) {
//                return $this->sendErrorResponse(400, '缺少参数');
//            }
//            $this->db->begin();
//            $this->runUserAttend($staffName, $staffNumber, $startTime, $endTime);
//            $this->db->commit();
//            return $this->sendSuccessResponse('生成成功');
//        } catch (\Exception $e) {
//            $this->db->rollback();
//            return $this->sendErrorResponse(
//                500,
//                $e->getMessage(),
//                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
//            );
//        }
//    }

    /**
     * 生成考勤记录
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181116
     */
//    public function generateDepAttendAction()
//    {
//        try {
//            $depId     = $this->request->getPost('depId', 'int');
//            $startTime = $this->request->getPost('startTime', 'string');
//            $endTime   = $this->request->getPost('endTime', 'string');
////            $staffId   = $this->request->getPost('staffId', 'int');
//            if (!$depId || !$startTime || !$endTime) {
//                return $this->sendErrorResponse(400, '缺少参数');
//            }
//            $staffArr = XhhrmStaff::find([
//                'columns'     => 'iStaffId,sStaffName',
//                'conditions' => 'bDelete = 0 and sDepIds like :depId: and iStaffStatus = 1',
//                'bind'       => ['depId' => '%,'.$depId.',%']
//            ])->toArray();
//            $totalNum = count($staffArr);
//            $successNum = 0;
//            $errorNum = 0;
//            $errorArr = [];
//            foreach ($staffArr as $index => $staff) {
//                try {
//                    $staffName = $staff['sStaffName'];
//                    $staffNumber = sprintf("xh%05d", $staff['iStaffId']);
//                    $this->runUserAttend($staffName, $staffNumber, $startTime, $endTime);
//                    $successNum++;
//                } catch (XhException $e) {
//                    $errorNum++;
//                    $errorArr []= [
//                        'desc' => "工号为{$staffNumber}的{$staffName},{$startTime}至{$endTime}的记录更新失败;",
//                        'detail' => $e->getDescription(true)
//                    ];
//                    continue;
//                }
//            }
//            if ($errorNum && $errorArr) {
//                $this->createCommitLog(
//                    '人力考勤生成错误信息',
//                    json_encode($errorArr, JSON_UNESCAPED_UNICODE)
//                );
//            }
//            return $this->sendSuccessResponse("生成成功，共执行{$totalNum}次,成功{$successNum}次，失败{$errorNum}次");
//        } catch (\Exception $e) {
//            return $this->sendErrorResponse(
//                500,
//                $e->getMessage(),
//                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
//            );
//        }
//    }

    /**
     * 生成个人考勤记录
     *
     * @param $staffName
     * @param $staffNumber
     * @param $startTime
     * @param $endTime
     *
     * @return bool
     * @throws XhException
     *
     * create by dale  20181116
     */
//    public function runUserAttend($staffName, $staffNumber, $startTime, $endTime)
//    {
//        $recordArr = XhhrmAttendRecord::find([
//            'conditions' => 'bDelete = 0 and sStaffNumber = :staffNumber: and sDay >= :startTime:
//                and sDay <= :endTime:',
//            'bind'       => ['staffNumber' => $staffNumber, 'startTime' => $startTime, 'endTime' => $endTime]
//        ])->toArray();
////        if (!$recordArr) {
////            throw new XhException('所选的时间段内一条记录都没有');
////        }
//        $dateRecordArr = [];
//        if ($recordArr) {
//            foreach ($recordArr as $record) {
//                $dateRecordArr[$record['sDay']][] = $record;
//            }
//        }
//        $weekArr = ["日","一","二","三","四","五","六"];
//        for ($i = $startTime; $i <= $endTime; $i = date('Y-m-d', strtotime("$i +1 day"))) {
//            $obj = XhhrmAttend::findFirst([
//                'conditions' => 'bDelete = 0 and sDay = :sDay: and sStaffNumber = :sStaffNumber:',
//                'bind'       => ['sDay' => $i, 'sStaffNumber' => $staffNumber]
//            ]);
//            if (!$obj) {
//                $obj = new XhhrmAttend();
//                $obj->sStaffName   = $staffName;
//                $obj->sStaffNumber = $staffNumber;
//                $obj->sDay = $i;
//                $obj->sWeek = '星期'. $weekArr[date('w', strtotime($i))];
//                $bHoliday = $this->checkHoliday($i);
//                if ($bHoliday) {
//                    $obj->bHoliday = 1;
//                }
//            } else { //已经有记录以记录的假期为准
//                $bHoliday = $obj->bHoliday;
//                $obj->assign($this->clearAttendData());//清除数据
//            }
//            $dayRecordArr = Tool::getValue($dateRecordArr, $i, []);
//            if (!$dayRecordArr) {
//                if ($bHoliday) {
//                    $obj->iLateType = 0;
//                    $obj->iEarlyType = 0;
//                    $obj->dAbsent = 0;
//                    if (!$obj->save()) {
//                        throw new XhException('保存失败');
//                    }
//                } else {
//                    $obj->iLateType  = 3;
//                    $obj->iEarlyType = 3;
//                    $obj->dAbsent = 1;
//                    if (!$obj->save()) {
//                        throw new XhException('保存失败');
//                    }
//                }
//            }
//            foreach ($dayRecordArr as $dayRecord) { //循环
//                if (!$this->checkRecordValid($dayRecord['sSignStatus'])) { //打卡无效
//                    continue;
//                }
//                if (!$bHoliday) { //不在假期
//                    if ($dayRecord['sAttendTime'] == $i.' 09:00') { //上午
//                        $obj->sSignIn = $dayRecord['sSignTime'];
//                        $obj->iLateType = $this->getLateType($dayRecord['sSignStatus'], $i, $dayRecordArr['sSignTime']);
//                    } elseif ($dayRecord['sAttendTime'] == $i.' 17:30') { //下午
//                        $obj->sSignOut = $dayRecord['sSignTime'];
//                        $obj->iEarlyType = $this->getEarlyType($dayRecord['sSignStatus'], $i, $dayRecordArr['sSignTime']);
////                        if ($obj->iEarlyType == 1) {
////                            $obj->iEarlyType = $this->fixEarlyType($obj->sDay, $obj->sSignOut);
////                        }
//                    }
//                } else { //假期
//                    $obj->assign($this->signInHoliday($obj->toArray(), $dayRecord, $i));
////                    var_dump($obj->sSignIn);die;
//                }
//            }
//
//            $fixArr = $this->fixLateEarlyType($obj->sSignIn, $obj->sSignOut, $bHoliday);
//            if ($fixArr) {
//                $obj->assign($fixArr);
//            }
//            if ($obj->iLateType == 3 || $obj->iEarlyType == 3) {  //可能存在两个都旷工
//                $obj->dAbsent = 0.5;
//            }
//            if ($obj->iLateType == 3 && $obj->iEarlyType == 3) { //两个都旷工 记未旷工1天
//                $obj->dAbsent = 1;
//            }
//            if ($obj->iLateType == 7 || $obj->iEarlyType == 7) {
//                $obj->dOffDay = 0.5;
//            }
//            if ($obj->iLateType == 7 && $obj->iEarlyType == 7) {
//                $obj->dOffDay = 1;
//            }
//            if ($obj->iLateType == 4 || $obj->iEarlyType == 4) {  //可能存在两个都补卡
//                $obj->iFixSign = 1;
//            }
//            if ($obj->iLateType == 4 && $obj->iEarlyType == 4) { //两个都都补卡
//                $obj->iFixSign = 2;
//            }
//            $overArr = $this->calculateOverTime($i, $obj->sSignIn, $obj->sSignOut, $bHoliday, $obj->sCheckInfo);
//            $obj->assign($overArr);
//            if (!$obj->save()) {
//                throw new XhException('保存失败');
//            }
//        }
//        return true;
//    }

    /**
     * 获取周末上下班打卡
     *
     * @param $objArr
     * @param $dayRecord
     * @param $day
     *
     * @return array
     *
     * create by dale  20181116
     */
    public function signInHoliday($objArr, $dayRecord, $day)
    {
        if (!$objArr['sSignIn']) {
            return [
                'sSignIn'   => $dayRecord['sSignTime'],
                'iLateType' => 0
            ];
        } else {
            return [
                'sSignOut'   => $dayRecord['sSignTime'],
                'iEarlyType' => 0
            ];
        }
//        if ($dayRecord['sSignTime'] <= $day.' 09:00') { //上午
//            return [
//                'sSignIn'   => $dayRecord['sSignTime'],
//                'iLateType' => 0,
//            ];
//        } elseif ($dayRecord['sSignTime'] > $day.' 09:00' && $dayRecord['sSignTime'] <= $day.' 09:30') {
//            return [
//                'sSignIn'   => $dayRecord['sSignTime'],
//                'iLateType' => 1
//            ];
//        } elseif ($dayRecord['sSignTime'] > $day.' 09:30' && $dayRecord['sSignTime'] <= $day.' 11:00') {
//            return [
//                'sSignIn'   => $dayRecord['sSignTime'],
//                'iLateType' => 2
//            ];
//        } elseif ($dayRecord['sSignTime'] > $day.' 11:00' && $dayRecord['sSignTime'] <= $day.' 12:00') {
//            return [
//                'sSignIn'   => $dayRecord['sSignTime'],
//                'iLateType' => 3
//            ];
//        } elseif ($dayRecord['sAttendTime'] > $day.' 12:00') { //下午
//            return [
//                'sSignOut'   => $dayRecord['sSignTime'],
//                'iEarlyType' => $this->getEarlyType($dayRecord['sSignStatus'])['iEarlyType']
//            ];
//        }
    }


    /**
     * 改变某一天 为工作日 或 假期
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181116
     */
    public function changeHolidayAction()
    {
        try {
            $bHoliday = $this->request->getPost('bHoliday', 'int'); //1 工作日 2 假期
            $day = $this->request->getPost('day', 'string');
            $staffNumber = $this->request->getPost('staffNumber', 'string');
            if (!$day || !$bHoliday || !$staffNumber) {
                return $this->sendErrorResponse(400, '缺少参数');
            }
            $this->getUserAttend($day, $staffNumber, $bHoliday);
            return $this->sendSuccessResponse('此人当天记录更新成功');
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 生成当天用户考勤
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181116
     */
//    public function generateUserAttendAction()
//    {
//        try {
//            $staffNumberArr = $this->request->getPost('staffNumberArr', 'string');
//            $dayArr = $this->request->getPost('dayArr', 'string');
//            if (!$staffNumberArr || !$dayArr) {
//                return $this->sendErrorResponse(500, '缺少参数');
//            }
//            $totalNum = count($dayArr);
//            $successNum = 0;
//            $errorNum = 0;
//            $errorArr = [];
//            foreach ($dayArr as $index => $day) {
//                try {
//                    $staffNumber = Tool::getValue($staffNumberArr, $index, '');
//                    if ($staffNumber) {
//                        $this->getUserAttend($day, $staffNumber);
//                        $successNum++;
//                    } else {
//                        $errorNum++;
//                    }
//                } catch (XhException $e) {
//                    $errorNum++;
//                    $errorArr []= [
//                        'desc' => "工号为{$staffNumber},{$day}的记录更新失败;",
//                        'detail' => $e->getDescription(true)
//                    ];
//                    continue;
//                }
//
//            }
//            if ($errorNum && $errorArr) {
//                $this->createCommitLog(
//                    '人力考勤生成错误信息',
//                    json_encode($errorArr, JSON_UNESCAPED_UNICODE)
//                );
//            }
//
//            return $this->sendSuccessResponse("更新成功，共执行{$totalNum}次,成功{$successNum}次，失败{$errorNum}次");
//        } catch (\Exception $e) {
//            return $this->sendErrorResponse(
//                500,
//                $e->getMessage(),
//                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
//            );
//        }
//    }

    /**
     * 重新生成某人某一天
     *
     * @param $today
     * @param $staffNumber
     * @param $bHoliday  (1 => 工作日 2 => 假期 )
     *
     * @return bool
     * @throws XhException
     *
     * create by dale  20181116
     */
    private function getUserAttend($today, $staffNumber, $bHoliday = false)
    {
        $obj = XhhrmAttend::findFirst([
            'conditions' => 'bDelete = 0 and sStaffNumber = :staffNumber: and sDay = :today:',
            'bind'       => ['staffNumber' => $staffNumber, 'today' => $today]
        ]);
        if (!$obj) {
            throw new XhException('当天考勤记录还未生成，请先生成');
        }
        $recordArr = XhhrmAttendRecord::find([
            'conditions' => 'bDelete = 0 and sStaffNumber = :staffNumber: and sDay = :today:',
            'bind'       => ['staffNumber' => $staffNumber, 'today' => $today]
        ])->toArray();
        if ($bHoliday) {
            $bHoliday = $bHoliday - 1;
            $obj->bHoliday = $bHoliday;
        } else {
            $bHoliday = $obj->bHoliday;
        }
        $obj->assign($this->clearAttendData());
        if (!$recordArr) {
            if ($bHoliday) { //假期
                $obj->iLateType = 0;
                $obj->iEarlyType = 0;
                $obj->dAbsent = 0;
                if (!$obj->save()) {
                    throw new XhException('保存失败');
                }
            } else { //工作日判断是否请假

                $obj->iLateType  = 3;
                $obj->iEarlyType = 3;
                $obj->dAbsent = 1;
                if (!$obj->save()) {
                    throw new XhException('保存失败');
                }
            }
        }
        foreach ($recordArr as $dayRecord) { //循环
            if (!$this->checkRecordValid($dayRecord['sSignStatus'])) { //打卡无效
                continue;
            }
            if (!$bHoliday) { //不在假期
                if ($dayRecord['sAttendTime'] == $today.' 09:00') { //上午
                    $obj->sSignIn = $dayRecord['sSignTime'];
                    $obj->iLateType = $this->getLateType($dayRecord['sSignStatus'], $today, $dayRecord['sSignTime']);
                } elseif ($dayRecord['sAttendTime'] == $today.' 17:30') { //下午
                    $obj->sSignOut = $dayRecord['sSignTime'];
                    $obj->iEarlyType = $this->getEarlyType($dayRecord['sSignStatus'], $today, $dayRecord['sSignTime']);
                }
            } else { //假期
                $obj->assign($this->signInHoliday($obj->toArray(), $dayRecord, $today));
            }
        }
        $fixArr = $this->fixLateEarlyType($obj->sSignIn, $obj->sSignOut, $bHoliday);
        if ($fixArr) {
            $obj->assign($fixArr);
        }
        $specialArr = $this->getSpecialArr($obj->iLateType, $obj->iEarlyType);
        if ($specialArr) {
            $obj->assign($specialArr);
        }
        $overArr = $this->calculateOverTime($today, $obj->sSignIn, $obj->sSignOut, $bHoliday, $obj->sCheckInfo);
        $obj->assign($overArr);
        if (!$obj->save()) {
            throw new XhException('保存失败');
        }
        return true;
    }

    /**
     * 清除其他数据
     *
     * @return array
     *
     * create by dale  20181116
     */
    private function clearAttendData()
    {
        return [
            'sSignIn' => '',
            'sSignOut' => '',
            'iLateType' => 0,
            'iEarlyType' => 0,
            'dAbsent' =>  0,
            'dOverTime' => 0,
            'dOverWeek' => 0,
            'dOffDay' => 0,
            'iMeal' => 0,
            'iFixSign' => 0
        ];
    }


    /**
     * 获取迟到时间
     *
     * @param $signInStatus
     * @param $date
     * @param $signIn
     *
     * @return string
     *
     * create by dale  20181115
     * modify by dale 20181122  严重迟到判断
     * modify by dale 20181210  添加缺卡为10
     */
    public function getLateType($signInStatus, $date, $signIn = '')
    {
        $enums = [
            '迟到'     => 1,
            '严重迟到' => 2,
            '旷工迟到' => 3,
            '缺卡' => 10,
            '未打卡' => 10,
            '补卡' => 4,
            '出差' => 5,
            '外勤' => 6,
            '请假' => 7
        ];
        $lateType = 0;
        foreach ($enums as $val => $type) {
            if (strpos($signInStatus, $val) !== false) {
                $lateType = $type;
            }
        }
        if ($lateType == 1) {
            if (!$signIn) {
                return 10; //缺卡
            }
            if ($signIn >= $date.' 11:00') { //旷工早退
                return 3;
            } elseif ($signIn >= $date.' 9:30') {
                return 2;
            } else {
                return 1;
            }
        }
        return $lateType;
    }

    /**
     * 修复早退类型
     *
     * @param $date
     * @param $signOut
     *
     * @return int
     *
     * create by dale  20181120
     */
    public function fixEarlyType($date, $signOut)
    {
        if (!$signOut) {
            return 3; //旷工早退
        }
        if ($signOut <= $date.' 15:30') {
            return 3;
        } elseif ($signOut <= $date.' 17:00') {
            return 2;
        } else {
            return 1;
        }
    }

    /**
     * 获取早退时间
     *
     * @param $signOutStatus
     * @param $date
     * @param $signOut
     *
     * @return string
     *
     * create by dale  20181115
     * modify by dale 20181122  严重早退判断
     * modify by dale 20181210  添加缺卡为10
     */
    public function getEarlyType($signOutStatus, $date, $signOut = '')
    {
        $enums = [
            '早退'     => 1,
            '严重早退' => 2,
            '旷工早退' => 3,
            '缺卡' => 10,
            '未打卡' => 10,
            '补卡' => 4,
            '出差' => 5,
            '外勤' => 6,
            '请假' => 7
        ];
        $earlyType = 0;
        foreach ($enums as $val => $type) {
            if (strpos($signOutStatus, $val) !== false) {
                $earlyType = $type;
            }
        }
        if ($earlyType == 1) {
            if (!$signOut) {
                return 10; //旷工早退
            }
            if ($signOut <= $date.' 15:30') {
                return 3;
            } elseif ($signOut <= $date.' 17:00') {
                return 2;
            } else {
                return 1;
            }
        }
        return $earlyType;
    }

    /**
     * 检查假日
     *
     * @param $day
     *
     * @return integer
     *
     * create by dale  20181115
     */
    public function checkHoliday($day)
    {
        if (!$day) {
            return 0;
        }
        $weekNumber = date('w', strtotime($day)) + 1;
        if ($weekNumber == 1 || $weekNumber == 7) {
            return 1;
        }
        return 0;
    }

    /**
     * 判断打卡是否有效
     *
     * @param $status
     *
     * @return bool
     *
     * create by dale  20181115
     */
    public function checkRecordValid($status)
    {
        if (!$status) {
            return false;
        }
        if (strpos($status, '打卡无效') !== false) {
            return false;
        }
        return true;
    }

    /**
     * 计算加班
     *
     * @param $date
     * @param $signIn
     * @param $signOut
     * @param bool $bHoliday
     * @param $sCheckInfo
     * @param $ruleName
     *
     * @return array
     *
     * create by dale  20181115
     * modify by dale 20181212   添加对审批单的处理， 添加工作时长，加班时长，异常数据的设置
     */
    public function calculateOverTime($date, $signIn, $signOut, $bHoliday = false, $sCheckInfo = '', $ruleName = 'moduleOne')
    {
        $rule = self::$rules[$ruleName];
        $arr = ['dOverTime' => 0, 'iMeal' => 0, 'dOverWeek' => 0, 'dWorkHour' => 0, 'dOverHour' => 0];
        if ($signOut && $signIn) { //工作时长
            $timeLong  = strtotime($signOut)  - strtotime($signIn);
            $timeLong = sprintf("%.2f", floatval($timeLong/3600));
            $arr['dWorkHour'] = $timeLong < 0 ? 0 : $timeLong;
        }
        if (!$sCheckInfo) {
            return $arr;
        }
        if (strpos($sCheckInfo, '加班') === false) {
            return $arr;
        }
        $tomorrow = date('Y-m-d', strtotime("$date +1 day"));
        if (!$signOut) { //没有签退
            if ($ruleName == 'moduleTwo') {
                $arr['bUnusual'] = 1;
            }
            return $arr;
        }
        if ($bHoliday) { //假期
            if (!$signIn) { //没有签到
                if ($ruleName == 'moduleTwo') {
                    $arr['bUnusual'] = 1;
                }
                return $arr;
            }
            if ($ruleName == 'moduleOne') {
                $timeLong  = strtotime($signOut)  - strtotime($signIn);
                $timeLong = intval($timeLong/3600);
                if ($timeLong >= 4) {
                    $arr['iMeal'] = 1;
                    $arr['dOverWeek'] = 0.5;
                }
                if ($timeLong >= 8) {
                    $arr['iMeal'] = 2;
                    $arr['dOverWeek'] = 1;
                }
                if ($timeLong >= 12) {
                    $arr['iMeal'] = 2;
                    $arr['dOverWeek'] = 1;
                    $arr['dOverTime'] = 0.5;
                }
                if ($timeLong >= 16) {
                    $arr['iMeal'] = 2;
                    $arr['dOverWeek'] = 1;
                    $arr['dOverTime'] = 1;
                }
            } elseif ($ruleName == 'moduleTwo') {
                $weekRules = $rule['overWeek'];
                foreach ($weekRules as $weekRule) { //根据条件循环判断从属那一个加班
                    if ($signIn > $date.' '.$weekRule['in'][0] && $signIn <= $date.' '.$weekRule['in'][1]) {
                        foreach ($weekRule['out'] as $timePeriod) {
                            if ($timePeriod == '00:00') {
                                if ($signOut >= $tomorrow.' 00:00') {
                                    $arr['iMeal'] += 1;
                                    $arr['dOverTime'] += 0.5;
                                }
                            } else {
                                if ($signOut >= $date.' '.$timePeriod) {
                                    $arr['iMeal'] += 1;
                                    if ($timePeriod < '18:00') {
                                        $arr['dOverWeek'] += 0.5;
                                    } else {
                                        $arr['dOverTime'] += 0.5;
                                    }
                                }
                            }

                        }
                    }
                }
            }
            $arr['iMeal'] = $arr['iMeal'] > 2 ? 2 : $arr['iMeal']; //餐补至多两次
        } else { //工作日
            if ($signOut >= $date.' 21:00') {
                $arr['iMeal'] = 1;
                $arr['dOverTime'] = 0.5;
            }
            if ($signOut >= $tomorrow.' 00:00') {
                $arr['iMeal'] = 2;
                $arr['dOverTime'] = 1;
            }
        }
        if ($bHoliday) { //休息日  加班时长 == 工作时长
            $arr['dOverHour'] = $arr['dWorkHour'];
        } else { //工作日 加班时长计算
            $timeLong  = strtotime($signOut)  - strtotime($date.' 18:00');
            $timeLong = sprintf("%.2f", floatval($timeLong/3600));
            $arr['dOverHour'] = $timeLong < 0 ? 0 : $timeLong;
        }
        if ($arr['dOverHour'] > 0) { //处理加班问题
            $queueRecord = '';
            $overRecordArr = explode("\n", $sCheckInfo);
            if ($overRecordArr) {
                foreach ($overRecordArr as $overRecord) {
                    if (strpos($overRecord, '加班') !==  false) {
                        $queueRecord = $overRecord;
                    }
                }
                if ($queueRecord) {
                    $queueRecord = explode(' ', $queueRecord);
                    $queueRecord = end($queueRecord);
                    $recordTimeLong = floatval($queueRecord);
                    $absNum = abs($arr['dOverHour'] - $recordTimeLong);
                    if ($bHoliday && $absNum > 0.5) {
                        $arr['bUnusual'] = 1;
                    }
                }
            }
        }
//        var_dump($arr);die;
        return $arr;
    }

    /**
     * 补全上班打卡下班打卡状态
     *
     * @param $signIn
     * @param $signOut
     * @param bool $bHoliday
     *
     * @return array
     *
     * create by dale  20181116
     * modify by dale 20181210   修改补全信息
     */
    public function fixLateEarlyType($signIn, $signOut, $bHoliday = false)
    {
        $arr = [];
        if ($bHoliday) { //假期
            if (!$signIn) {
                $arr['iLateType'] = 0;
            }
            if (!$signOut) {
                $arr['iEarlyType'] = 0;
            }
        } else { //不在假期
            if (!$signIn && $signOut) { //没有签到 有签退
                $arr['iLateType'] = 10;
            } elseif (!$signOut && $signIn) {
                $arr['iEarlyType'] = 10;
            } elseif (!$signIn && !$signOut) {
                $arr['iEarlyType'] = 10;
                $arr['iLateType'] = 10;
            }
        }
        return $arr;
    }


    /**
     * 检查记录是否需要记录
     *
     * @param $signStatus
     *
     * @return bool
     *
     * create by dale  20181115
     */
    public function checkStatus($signStatus)
    {
        if (!$signStatus) {
            return false;
        }
        if (strpos($signStatus, '打卡无效') !== false) {
            return false;
        }
        return true;
    }

    /**
     * 考勤列表
     *
     * @return \Phalcon\Mvc\View|string
     *
     * create by dale  20181116
     */
    public function attendDetailAction()
    {
        try {
            if (!Power::exist('Hrm_AttendDetail')) {
                return $this->sendViewError('缺少权限');
            }
            $startTime = $this->request->getQuery('startTime', 'string', '');
            $endTime = $this->request->getQuery('endTime', 'string', '');
            Assets::easyUI();
//            $this->view->setTemplateBefore('listForm');
            Assets::importJs('js/attendance/attendDetail.js');
            $this->view->pick('attendance/attendDetail');
            Template::exists('Attend_Detail', 'list') or die(Main::showMessageModal('配置文件不存在，请先创建！', 109106002));
            $listButtonArr = $formButtonArr = $listSearchArr = $listButtonArr2 = array();
//            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_seeRecord', 'text' => '点击查看打卡记录',
//                'icon' => 'fa-eye');
            if (Power::exist('Hrm_AttendDetail_Edit')) {
                $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_holidayMenu', 'text' => '假期设置',
                    'class' => 'bt_list_menu');
                $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_changeNormal', 'text' => '修改为正常',
                    'icon' => 'fa-pencil');
                $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_changeOver', 'text' => '修改加班',
                    'icon' => 'fa-pencil');
                $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_signNormal', 'text' => '标记为正常',
                    'icon' => 'fa-star');
            }
            $listSearchArr[] = ['type'=>'select', 'id'=>'select_unusual',
                'data'=>[
                        0 => '全部',
                        1 => '正常',
                        2 => '异常'
                    ],
                'default' => '0' ];
            $listSearchArr[] = ['type'=>'select', 'id'=>'select_holiday',
                'data'=> [
                        0 => '考勤类型',
                        1 => '工作日',
                        2 => '休息日'
                    ],
                'default' => '0' ];
            $listSearchArr[] = ['type'=>'select', 'id'=>'select_overWork',
                'data'=> [
                    0 => '是否加班',
                    1 => '未加班',
                    2 => '加班'
                ],
                'default' => '0' ];
            $listSearchArr[] = ['type'=>'select', 'id'=>'select_offType',
                'data'=> [0 => '请假类型'] + self::$enums['iOffType'], 'default' => '0' ];
            $listSearchArr[] = ['type'=>'select', 'id'=>'select_lateType',
                'data'=> [0 => '上班状态'] + self::$enums['iLateType'], 'default' => '0' ];
            $listSearchArr[] = ['type'=>'select', 'id'=>'select_earlyType',
                'data'=> [0 => '下班状态'] + self::$enums['iEarlyType'], 'default' => '0' ];
            $listSearchArr[] = array('type' => 'text', 'class'  => 'easyui-datebox', 'id' => 'List_Search_StartTime',
                'label' => ' 时间段：','style'=>'width:100px;','value' => $startTime);
            $listSearchArr[] = array('type' => 'text', 'class' => 'easyui-datebox', 'id' => 'List_Search_EndTime',
                'label' => ' ~ ', 'style' => 'width:100px;', 'value' => $endTime);
            $listSearchArr[] = array('type' => 'text', 'id' => 'list_search', 'label' => ' 搜索： ');
            $listSearchArr[] = array('type' => 'button', 'id' => 'bt_list_search', 'text' => '查找',
                'icon' => 'fa-search', 'style' => 'margin-left:10px');

            //原始记录
            $listButtonArr1[] = array('plain' => 'true', 'id' => 'bt_list_fixSign', 'text' => '修改打卡记录',
                'icon' => 'fa-pencil');
            return $this->view->setVars(array(
                'List' => Template::createList('detailList', 'Attend_Detail', [
                    'searchToolbar' => Template::createSearchToolBar($listSearchArr, !!$listButtonArr),
                    'buttonToolbar' => Template::createButtonToolBar($listButtonArr),
                ]),
                'recordList' => Template::createList('recordList', 'Attend_Record', [
//                    'searchToolbar' => Template::createSearchToolBar($listSearchArr1, !!$listButtonArr1),
                    'buttonToolbar' => Template::createButtonToolBar($listButtonArr1),
                    'tableAttr' => [
                        'singleSelect' => 'true',
                    ],
                    'field' => ['iSARId','sStaffNumber','sDay','sStaffName','sAttendTime','sSignTime','sSignStatus','sSignAddress','sSignDev']
                ])
            ));
        } catch (\Exception $e) {
            return $this->sendViewError(
                $e->getMessage()
            );
        }
    }

    /**
     * 每日考勤设置
     *
     * @return \Phalcon\Mvc\View|string
     *
     * create by dale  20181121
     */
//    public function setAttendListAction()
//    {
//        try {
//            $startTime = $this->request->getQuery('startTime', 'string', '');
//            $endTime = $this->request->getQuery('endTime', 'string', '');
//            Assets::easyUI();
//            Assets::importJs('js/attendance/setAttendList.js');
//            $this->view->pick('attendance/setAttendList');
//            Template::exists('Attend_Detail', 'list') or die(Main::showMessageModal('配置文件不存在，请先创建！', 109106002));
//            $listButtonArr = $listSearchArr = [];
//            $listButtonArr1 = $listSearchArr1 = [];
////            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_import', 'text' => '导入假期补充',
////                'icon' => 'fa-pencil');
////            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_generate', 'text' => '重新生成',
////                'icon' => 'fa-refresh');
////            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_holidayMenu', 'text' => '假期设置',
////                'class' => 'bt_list_menu');
////            $listSearchArr[] = ['type'=>'select', 'id'=>'select_offType',
////                'data'=> [0 => '请假类型'] + self::$enums['iOffType'], 'default' => '0' ];
////            $listSearchArr[] = ['type'=>'select', 'id'=>'select_lateType',
////                'data'=> [0 => '上班状态'] + self::$enums['iLateType'], 'default' => '0' ];
////            $listSearchArr[] = ['type'=>'select', 'id'=>'select_earlyType',
////                'data'=> [0 => '下班状态'] + self::$enums['iEarlyType'], 'default' => '0' ];
//            $listSearchArr[] = array('type' => 'text', 'class'  => 'easyui-datebox', 'id' => 'List_Search_StartTime',
//                'label' => ' 时间：','style'=>'width:80px;','value' => $startTime);
//            $listSearchArr[] = array('type' => 'text', 'class' => 'easyui-datebox', 'id' => 'List_Search_EndTime',
//                'label' => ' ~ ', 'style' => 'width:80px;', 'value' => $endTime);
//            $listSearchArr[] = array('type' => 'text', 'id' => 'list_search', 'label' => ' 搜索： ');
//            $listSearchArr[] = array('type' => 'button', 'id' => 'bt_list_search', 'text' => '查找',
//                'icon' => 'fa-search', 'style' => 'margin-left:10px');
//
//            $listButtonArr1[] = array('plain' => 'true', 'id' => 'bt_list_fixSign', 'text' => '修改打卡记录',
//                'icon' => 'fa-pencil');
//            return $this->view->setVars(array(
//                'detailList' => Template::createList('detailList', 'Attend_Detail', [
//                    'searchToolbar' => Template::createSearchToolBar($listSearchArr, !!$listButtonArr),
//                    'buttonToolbar' => Template::createButtonToolBar($listButtonArr),
//                    'tableAttr' => array(
//                        'singleSelect' => 'true'
//                    )
//                ]),
//                'recordList' => Template::createList('recordList', 'Attend_Record', [
////                    'searchToolbar' => Template::createSearchToolBar($listSearchArr1, !!$listButtonArr1),
//                    'buttonToolbar' => Template::createButtonToolBar($listButtonArr1),
//                    'tableAttr' => [
//                        'singleSelect' => 'true',
//                    ],
//                    'field' => ['iSARId','sStaffNumber','sDay','sStaffName','sAttendTime','sSignTime','sSignStatus']
//                ])
//            ));
//        } catch (\Exception $e) {
//            return $this->sendViewError(
//                $e->getMessage()
//            );
//        }
//    }

    /**
     * 处理状态
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181124
     */
    public function dealStatusAction()
    {
        try {
            if (!Power::exist('Hrm_AttendDetail_Edit')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $id = $this->request->getPost('id', 'int');
            $status = $this->request->getPost('status', 'string');  //设置为正常
            $attendType = $this->request->getPost('attendType', 'string');
            if (!$id || !$status || !$attendType) {
                return $this->sendErrorResponse(400, '缺少参数');
            }
            if ($status > 1) {
                return $this->sendErrorResponse(400, '暂不支持修改除正常以外的状态');
            }
            $obj = XhhrmAttend::findFirst($id);
            if (!$obj) {
                return $this->sendErrorResponse(400, '未找到当日的考勤记录');
            }
            $str = '考勤管理员：'.Main::getLoginUserInfo('userName').'修改';
            if ($attendType == 1) { //上午
                $obj->iLateType = $status -1;
                $str .= '上班状态为:';
            } elseif ($attendType == 2) { //下午
                $obj->iEarlyType = $status -1;
                $str .= '下班状态为:';
            }
            if ($status == 1) {
                $str .= '正常;'.PHP_EOL;
            }
            $obj->sFixDesc = $str;
            $obj->assign([
                'iFixSign' => 0,
                'dAbsent'  => 0,
                'dOffDay'  => 0
            ]);
            $specialArr = $this->getSpecialArr($obj->iLateType, $obj->iEarlyType);
            if ($specialArr) {
                $obj->assign($specialArr);
            }
            $overArr = $this->calculateOverTime(
                $obj->sDay,
                $obj->sSignIn,
                $obj->sSignOut,
                $obj->bHoliday,
                $obj->sCheckInfo
            );
            $obj->assign($overArr);
            if (!$obj->save()) {
                return $this->sendErrorResponse(500, '保存失败');
            }
            return $this->sendSuccessResponse('保存成功');
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 加班状态
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181124
     */
    public function changeOverAction()
    {
        try {
            if (!Power::exist('Hrm_AttendDetail_Edit')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $id = $this->request->getPost('id', 'int');
            $overWeek = $this->request->getPost('overWeek', 'string');
            $overWork = $this->request->getPost('overWork', 'string');
            if (!$id || !($overWeek || $overWork)) {
                return $this->sendErrorResponse(400, '无需修改加班');
            }
            $obj = XhhrmAttend::findFirst($id);
            if (!$obj) {
                return $this->sendErrorResponse(400, '未找到当日的考勤记录');
            }
            $str = '考勤管理员：'.Main::getLoginUserInfo('userName').'修改加班为:';
            $obj->iMeal = 0;
            if ($overWeek) {
                if ($obj->bHoliday != 1) {
                    return $this->sendErrorResponse(500, '不在休息日,无法修改为周末加班');
                }
                $obj->dOverWeek = floatval($overWeek/2);
                $str .='周末'.floatval($overWeek/2).'天';
            } else {
                $obj->dOverWeek = 0;
            }
            if ($overWork) {
                $obj->dOverTime = floatval($overWork/2);
                $str .='延时'.$overWork.'次';
            } else {
                $obj->dOverTime = $overWork;
            }
            $obj->iMeal = $obj->dOverWeek*2 + $obj->dOverTime*2;
            $obj->iMeal = $obj->iMeal >= 2 ? 2 : $obj->iMeal;
            $obj->sFixDesc .= $str.';'.PHP_EOL;
            if (!$obj->save()) {
                return $this->sendErrorResponse(500, '修改失败');
            }
            return $this->sendSuccessResponse('修改成功');
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }


    /**
     * 获取明细
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181116
     */
    public function getDetailAction()
    {
        try {
            if (!Power::exist('Hrm_AttendDetail')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $sStaffNumber = $this->request->getPost('staffNumber', 'string');
            $key       = $this->request->getPost('key', 'string');
            $startTime = $this->request->getPost('startTime', 'string');
            $endTime   = $this->request->getPost('endTime', 'string');
            $offType   = $this->request->getPost('offType', 'string');
            $lateType  = $this->request->getPost('lateType', 'string');
            $earlyType = $this->request->getPost('earlyType', 'string');
            $holiday   = $this->request->getPost('holiday', 'string');
            $overWork  = $this->request->getPost('overWork', 'string');
            $unusual    = $this->request->getPost('unusual', 'string');
            $attendColumns =  array_keys(get_object_vars(new XhhrmAttend()));
            $attendColumns = array_map(function ($val) {
                return 'a.' . $val;
            }, $attendColumns);
            $builder = $this->modelsManager->createBuilder()
                ->from(['a' => 'Admin\Models\hrm\XhhrmAttend'])
                ->columns(array_merge($attendColumns))
                ->where('a.bDelete = 0');
            if ($startTime) {
                $builder->andWhere('a.sDay >= :startTime:', ['startTime' => $startTime]);
            }
            if ($endTime) {
                $builder->andWhere('a.sDay <= :endTime:', ['endTime' => $endTime]);
            }
            if ($key) {
                $builder->andWhere(
                    'a.sStaffName like :key: or sWeek like :key: or sDay like :key: or sStaffNumber like :key:',
                    ['key' => '%'.$key.'%']
                );
            }
            if ($offType) {
                $builder->andWhere('a.iOffType = :iOffType:', ['iOffType' => $offType]);
            }
            if ($lateType) {
                $builder->andWhere('a.iLateType = :iLateType:', ['iLateType' => $lateType]);
            }
            if ($earlyType) {
                $builder->andWhere('a.iEarlyType = :iEarlyType:', ['iEarlyType' => $earlyType]);
            }
            if ($sStaffNumber) {
                $builder->andWhere('a.sStaffNumber = :sStaffNumber:', ['sStaffNumber' => $sStaffNumber]);
            }
            if ($holiday) {
                $holiday -= 1;
                $builder->andWhere('a.bHoliday = :bHoliday:', ['bHoliday' => $holiday]);
            }
            if ($unusual) {
                $unusual -= 1;
                $builder->andWhere('a.bUnusual = :bUnusual:', ['bUnusual' => $unusual]);
            }
            if ($overWork) {
                if ($overWork == 1) { //正常
                    $builder->andWhere('a.iMeal = :iMeal:', ['iMeal' => 0]);
                } elseif ($overWork == 2) { //加班
                    $builder->andWhere('a.iMeal > :iMeal:', ['iMeal' => 0]);
                }
            }
            $builder->orderBy('sStaffNumber , sDay ');
            $data = Main::runBuilderPage($builder);
            foreach ($data['rows'] as &$row) {
                $row['sWeek'] = "{$row['sDay']} ({$row['sWeek']})";
                $row['dayStar'] = $this->checkStr(
                    $row['iLateType'],
                    $row['iEarlyType'],
                    $row['dOverWeek'],
                    $row['dOverTime']
                );
                if ($row['bInAttend']) {
                    if ($row['bHoliday']) {
                        $row['sAttendType'] = '休息日';
                    } else {
                        $row['sAttendType'] = '工作日';
                    }

                } else {
                    $row['sAttendType'] = '不在考勤组';
                    $row['workTime'] = 0;
                    $row['overTime'] = 0;
                }
                $row = array_merge($row, ['late' => 0,'veryLate' => 0,'early' => 0,'veryEarly' => 0]);
                if ($row['iLateType'] == 1) {
                    $row['late'] = 1;
                } elseif ($row['iLateType'] == 2) {
                    $row['veryLate'] = 1;
                }
                if ($row['iEarlyType'] == 1) {
                    $row['early'] = 1;
                } elseif ($row['iEarlyType'] == 2) {
                    $row['veryEarly'] = 1;
                }
                if ($row['sFixDesc']) {
                    $row['sCheckInfo'] .=';'.PHP_EOL.$row['sFixDesc'];
                }
                if ($row['sCheckInfo']) {
                    $row['sCheckInfo'] = "<div title='{$row['sCheckInfo']}'>{$row['sCheckInfo']}</div>";
                }
                $this->runFloatVal($row, ['dOverWeek', 'dOverTime', 'dAbsent', 'dOffDay','dWorkHour','dOverHour']);
            }
            unset($row);
            Tool::runEnum($data['rows'], self::$enums);//替换字段
            return $this->sendJsonResponse($data);
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * float类型 去除多余小数点
     *
     * @param $arr
     * @param $nameArr
     *
     * @return bool
     *
     * create by dale  20181124
     */
    public function runFloatVal(&$arr, $nameArr)
    {
        foreach ($nameArr as $name) {
            $arr[$name] = floatval($arr[$name]);
        }
        return true;
    }


    /**
     * 考勤列表
     *
     * @return \Phalcon\Mvc\View|string
     *
     * create by dale  20181116
     * modify by dale 20190227  假期设置先不放上去
     */
    public function attendListAction()
    {
        try {
            if (!Power::exist('Hrm_Attend')) {
                return $this->sendViewError('缺少权限');
            }
            Assets::easyUI();
//            $this->view->setTemplateBefore('listForm');
            Assets::importJs('js/attendance/attendList.js');
            $this->view->pick('attendance/attendList');
            Template::exists('Attend_List', 'list') or die(Main::showMessageModal('配置文件不存在，请先创建！', 109106002));
            $listButtonArr = $formButtonArr = $listSearchArr = array();
            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_overTimeList', 'text' => '查看加班统计',
                'icon' => 'fa-eye');

//            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_holiday', 'text' => '假期设置',
//                'icon' => 'fa-pencil');
            if (Power::exist('Hrm_Attend_Add')) {
                $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_import', 'text' => '导入考勤信息',
                    'icon' => 'fa-pencil');
            }
            if (Power::exist('Hrm_Attend_Del')) {
                $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_del', 'text' => '删除考勤',
                    'icon' => 'fa-trash');
            }
            $startTime = date("Y-m", strtotime('-1 month')).'-26';
            $endTime   = date("Y-m").'-25';
            $listSearchArr[] = array('type' => 'text', 'class'  => 'easyui-datebox', 'id' => 'List_Search_StartTime',
                'label' => ' 时间段：','style'=>'width:100px;', 'value' => $startTime);
            $listSearchArr[] = array('type' => 'text', 'class' => 'easyui-datebox', 'id' => 'List_Search_EndTime',
                'label' => ' ~ ', 'style' => 'width:100px;', 'value' => $endTime);
            $listSearchArr[] = array('type' => 'text', 'id' => 'list_search', 'label' => ' 搜索： ');
            $listSearchArr[] = array('type' => 'button', 'id' => 'bt_list_search', 'text' => '查找',
                'icon' => 'fa-search', 'style' => 'margin-left:10px');
            $listSearchArr[] = array('type' => 'button', 'id' => 'excel_export', 'text' => '导出',
                'icon' => 'fa fa-file-excel-o');
            return $this->view->setVars(array(
                'List' => Template::createList('attendList', 'Attend_List', [
                    'searchToolbar' => Template::createSearchToolBar($listSearchArr, !!$listButtonArr),
                    'buttonToolbar' => Template::createButtonToolBar($listButtonArr),
                ]),
            ));
        } catch (\Exception $e) {
            return $this->sendViewError(
                $e->getMessage()
            );
        }
    }

    /**
     * 获取考勤信息
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181116
     */
    public function getAttendAction()
    {
        try {
            if (!Power::exist('Hrm_Attend')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $key       = $this->request->getPost('key', 'string');
            $startTime = $this->request->getPost('startTime', 'string');
            $endTime   = $this->request->getPost('endTime', 'string');
            $depTag    = $this->request->getPost('depTag', 'string');
            $sql  = "select sStaffName,sStaffNumber,sBaseNumber,SUM(dOverTime) as overTime,SUM(iMeal) as mealNum,";
            $sql .= "SUM(iFixSign) as fixSign,SUM(dOverWeek) as overWeek,";
            $sql .= "SUM(case when iOffType = 1 then dOffDay else 0 end) as loseOffDay, ";
            $sql .= "SUM(case when iOffType = 2 then dOffDay else 0 end) as thingOffDay, ";
            $sql .= "SUM(case when iOffType = 3 then dOffDay else 0 end) as yearOffDay, ";
            $sql .= "SUM(case when iOffType = 4 then dOffDay else 0 end) as skillOffDay, ";
            $sql .= "SUM(case when iOffType = 5 then dOffDay else 0 end) as offDay, ";
            $sql .= "SUM(case when iOffType = 6 then dOffDay else 0 end) as compBabyDay, ";
            $sql .= "SUM(case when iOffType = 7 then dOffDay else 0 end) as marryOffDay, ";
            $sql .= "SUM(case when iOffType = 8 then dOffDay else 0 end) as babyOffDay, ";
            $sql .= "count(case  when iLateType = 3 then iLateType else null end) as morAbsent, ";
            $sql .= "count(case  when iEarlyType = 3 then iEarlyType else null end) as afterAbsent, ";
            $sql .= "count(case  when iLateType = 10  then iLateType else null end) + count(case  when iEarlyType = 10  then iEarlyType else null end)  as absent, ";
            $sql .= "count(case  when iLateType = 1 then iLateType else null end) as late, ";
            $sql .= "count(case  when iLateType = 2 then iLateType else null end) as veryLate, ";
            $sql .= "count(case  when iEarlyType = 1 then iLateType else null end) as early, ";
            $sql .= "count(case  when iEarlyType = 2 then iLateType else null end) as veryEarly, ";
            $sql .= "SUM(case when bInAttend = 1 and bHoliday = 0 then 1 else 0 end) as attendNum,";
            $sql .= "SUM(case when bInAttend = 1 and bHoliday = 1  then 1 else 0 end) as offDayNum, ";
            $sql .= "count(case when bUnusual = 1 then bUnusual else null end) as unusual ";
            $sql .= " from XHHrm_Attend where bDelete = 0 ";

            $conditionArr = [];
            if ($startTime) {
                $conditionArr[] = " sDay >= '{$startTime}' ";
            }
            if ($endTime) {
                $conditionArr[] = " sDay <= '{$endTime}' ";
            }
            if ($key) {
                $key = "'%{$key}%'";
                $conditionArr[] = " ( sStaffName like {$key} or sWeek like {$key} or sDay like {$key} or sStaffNumber like {$key} )  ";
            }
            if ($conditionArr) {
                $sql .= 'and '. implode(' and ', $conditionArr);
            }
            if ($depTag) {
                $depTree = array_column(self::$depTree, null, 'depTag');
                $depInfo = Tool::getValue($depTree, $depTag);
                if ($depInfo && $depInfo['prefixRange']) {
                    $strArr = [];
                    foreach ($depInfo['prefixRange'] as $index => $row) {
                        $strArr[] = " sStaffNumber like  '%{$row}%' ";
                    }
                    $sql .='and ('. implode(' or ', $strArr) .')';
                }
            }
            $sql .= "  GROUP BY  sStaffNumber";
//            $sql = "select a.*,s.sDepIds,s.iStaffId from ({$sql}) as a
//                    LEFT JOIN  XHHrm_Staff as s on a.sStaffNumber = s.sStaffNumber ";


//            $sql .= " where s.bDelete = 0 ";
//            if ($depIds) {
//                if (!in_array('0', $depIds)) {
//                    $newDepCondition = [];
//                    foreach ($depIds as $depId) {
//                        $newDepCondition[] = " s.sDepIds like '%,{$depId},%' ";
//                    }
//                    $sql .= " and (" . implode('or', $newDepCondition) . ") ";
//                }
//            }
            $data = Main::runSqlPage(['query'=>"select :columns: from ({$sql}) as t",'columns'=>'t.*']);
            foreach ($data['rows'] as &$row) {
                $this->runFloatVal($row, [
                    'overTime', 'overWeek', 'absent', 'loseOffDay','thingOffDay', 'yearOffDay',
                    'skillOffDay', 'offDay', 'compBabyDay', 'marryOffDay','babyOffDay'
                ]);
                $row['realAtNum'] = $row['attendNum'] - $row['skillOffDay'] -$row['thingOffDay'] -
                    ($row['morAbsent'] + $row['afterAbsent'] + $row['absent'])/2;
                if ($row['unusual']) {
                    $row['sStaffName'] = "<div style='color: #CCCC66'>{$row['sStaffName']}</div>";
                } else {
                    $row['sStaffName'] = "<div>{$row['sStaffName']}</div>";
                }
            }
            unset($row);
            XhhrmDepart::runDepNameByDepId($data['rows'], ['sDepIds' => 'sDepName']);
            return $this->sendJsonResponse($data);
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 删除考勤记录
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181221
     */
    public function delAttendAction()
    {
        if (!Power::exist('Hrm_Attend_Del')) {
            return $this->sendErrorResponse(403, '缺少权限');
        }
        $baseNumber = $this->request->getPost('baseNumber', 'string');
        if (!$baseNumber) {
            return $this->sendErrorResponse(400, '缺少参数');
        }
        try {
            $this->db->begin();
            $attendArr = XhhrmAttend::find([
                'conditions' => 'bDelete = 0 and sBaseNumber = :baseNumber:',
                'bind'       => ['baseNumber' => $baseNumber]
            ]);
            if ($attendArr) {
                foreach ($attendArr as $attend) {
                    $attend->bDelete = 1;
                    if (!$attend->save()) {
                        throw new \Exception('删除考勤每日记录失败');
                    }
                }
            }
            $attendRecordArr = XhhrmAttendRecord::find([
                'conditions' => 'bDelete = 0 and sBaseNumber = :baseNumber:',
                'bind'       => ['baseNumber' => $baseNumber]
            ]);
            if ($attendRecordArr) {
                foreach ($attendRecordArr as $attend) {
                    $attend->bDelete = 1;
                    if (!$attend->save()) {
                        throw new \Exception('删除考勤每日记录失败');

                    }
                }
            }
            $this->db->commit();
            return $this->sendSuccessResponse('删除成功');
        } catch (\Exception $e) {
            $this->db->rollback();
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 导出考勤信息
     *
     * @return string
     *
     * create by dale  20181124
     * modify by dale 20181210  导出规则 添加旷工修改
     */
    public function exportAttendInfoAction()
    {
        try {
            if (!Power::exist('Hrm_Attend')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $this->view->disable();
            $startTime = $this->request->getQuery('startTime', 'string');
            $endTime   = $this->request->getQuery('endTime', 'string');
            $key       = $this->request->getQuery('key', 'string');
            $depTag    = $this->request->getQuery('depTag', 'string');
            if (!$startTime || !$endTime) {
                return $this->sendErrorResponse(500, '缺少开始时间结束时间');
            }
//            $key       = $this->request->getQuery('key', 'string');
            $sql  = "select sStaffName,sStaffNumber,SUM(dOverTime) as overTime,SUM(iMeal) as mealNum,";
            $sql .= "SUM(iFixSign) as fixSign,SUM(dOverWeek) as overWeek,";
            $sql .= "SUM(case when iOffType = 1 then dOffDay else 0 end) as loseOffDay, ";
            $sql .= "SUM(case when iOffType = 2 then dOffDay else 0 end) as thingOffDay, ";
            $sql .= "SUM(case when iOffType = 3 then dOffDay else 0 end) as yearOffDay, ";
            $sql .= "SUM(case when iOffType = 4 then dOffDay else 0 end) as skillOffDay, ";
            $sql .= "SUM(case when iOffType = 5 then dOffDay else 0 end) as offDay, ";
            $sql .= "SUM(case when iOffType = 6 then dOffDay else 0 end) as compBabyDay, ";
            $sql .= "SUM(case when iOffType = 7 then dOffDay else 0 end) as marryOffDay, ";
            $sql .= "SUM(case when iOffType = 8 then dOffDay else 0 end) as babyOffDay, ";
            $sql .= "count(case  when iLateType = 3 then iLateType else null end) as morAbsent, ";
            $sql .= "count(case  when iEarlyType = 3 then iEarlyType else null end) as afterAbsent, ";
            $sql .= "count(case  when iLateType = 10  then iLateType else null end) + count(case  when iEarlyType = 10  then iEarlyType else null end)  as absent, ";
            $sql .= "count(case  when iLateType = 1 then iLateType else null end) as late, ";
            $sql .= "count(case  when iLateType = 2 then iLateType else null end) as veryLate, ";
            $sql .= "count(case  when iEarlyType = 1 then iLateType else null end) as early, ";
            $sql .= "count(case  when iEarlyType = 2 then iLateType else null end) as veryEarly, ";
            $sql .= "SUM(case when bInAttend = 1 and bHoliday = 0 then 1 else 0 end) as attendNum,";
            $sql .= "SUM(case when bInAttend = 1 and bHoliday = 1  then 1 else 0 end) as offDayNum ";
            $sql .= " from XHHrm_Attend where bDelete = 0 ";
            $conditionArr = [];
            if ($startTime) {
                $conditionArr[] = " sDay >= '{$startTime}' ";
            }
            if ($endTime) {
                $conditionArr[] = " sDay <= '{$endTime}' ";
            }
            if ($key) {
                $key = "'%{$key}%'";
                $conditionArr[] = " ( sStaffName like {$key} or sWeek like {$key} or sDay like {$key} or sStaffNumber like {$key} )  ";
            }
            if ($conditionArr) {
                $sql .= 'and '. implode(' and ', $conditionArr);
            }
            if ($depTag) {
                $depTree = array_column(self::$depTree, null, 'depTag');
                $depInfo = Tool::getValue($depTree, $depTag);
                if ($depInfo && $depInfo['prefixRange']) {
                    $strArr = [];
                    foreach ($depInfo['prefixRange'] as $index => $row) {
                        $strArr[] = " sStaffNumber like  '%{$row}%' ";
                    }
                    $sql .='and ('. implode(' or ', $strArr) .')';
                }
            }
            $sql .= "  GROUP BY  sStaffNumber";

            $data = $this->db->fetchAll($sql);
            foreach ($data as &$row) {
                $this->runFloatVal($row, [
                    'overTime', 'overWeek', 'absent', 'loseOffDay','thingOffDay', 'yearOffDay',
                    'skillOffDay', 'offDay', 'compBabyDay', 'marryOffDay','babyOffDay'
                ]);
                $row['realAtNum'] = $row['attendNum'] - $row['skillOffDay'] -$row['thingOffDay'] -
                    ($row['morAbsent'] + $row['afterAbsent'] + $row['absent'])/2;
            }
            unset($row);
            $titleArr = [
                'sStaffNumber' => '工号',
                'sStaffName' => '职工名称',
                'attendNum' => '出勤天数',
                'offDayNum' => '休息天数',
                'realAtNum' => '实际出勤',
                'overTime' => '延时',
                'overWeek' => '周末',
                'mealNum' => '餐补(次)',
                'morAbsent' => '上班旷工',
                'afterAbsent' => '下班旷工',
                'absent' => '缺卡',
                'fixSign' => '补卡(次)',
                'late' => '迟到',
                'veryLate' => '严重迟到',
                'early' => '早退',
                'veryEarly' => '严重早退',
                'thingOffDay' => '事假',
                'offDay' => '调休',
                'skillOffDay' => '病假',
                'yearOffDay' => '年假',
                'loseOffDay' => '丧假',
                'compBabyDay' => '陪产假',
                'marryOffDay' => '婚假',
                'babyOffDay' => '产假'
            ];
            $dataSource = [];
            foreach ($data as $key => $examine) {
                $row = [];
                foreach ($titleArr as $filed => $name) {
                    $row[$filed] = Tool::getValue($examine, $filed);
                }
                $dataSource[] = $row;
            }
            //数据处理完毕
            unset($data);
            $xmlName = "考勤统计{$startTime}至{$endTime}";
//            if ($key) {
//                $xmlName .= ",关键字:{$key}";
//            }
            $spreadsheet = new Spreadsheet();
            $worksheet = $spreadsheet->getActiveSheet();
            $worksheet->getDefaultColumnDimension()->setWidth(12);
            $cell = 1;
            foreach ($titleArr as $key => $title) {
                $worksheet->setCellValueByColumnAndRow($cell, 3, is_array($title) ? $title['name'] : $title);
                $cell++;
            }
            $worksheet->mergeCells('A1:X1');
            $titleStyle = $worksheet->setCellValueExplicit(
                'A1',
                $xmlName.PHP_EOL.'生成时间:'.date("Y-m-d H:i:s"),
                DataType::TYPE_STRING
            )->getStyle('A1');
            $titleStyle->getFont()->setSize(18);
            $titleStyle->getAlignment()->setWrapText(true);
            $worksheet->getRowDimension('1')->setRowHeight(57);
            $worksheet->mergeCells('A2:A3');
            $worksheet->setCellValueExplicit('A2', '工号', DataType::TYPE_STRING);
            $worksheet->getColumnDimension('A')->setWidth(20);

            $worksheet->mergeCells('B2:B3');
            $worksheet->setCellValueExplicit('B2', '职工名称', DataType::TYPE_STRING);
            $worksheet->getColumnDimension('B')->setWidth(16);

            $worksheet->mergeCells('C2:E2');
            $worksheet->setCellValueExplicit('C2', '考勤(天)', DataType::TYPE_STRING);
            $worksheet->mergeCells('F2:H2');
            $worksheet->setCellValueExplicit('F2', '加班(天)', DataType::TYPE_STRING);

            $worksheet->mergeCells('I2:K2');
            $worksheet->setCellValueExplicit('I2', '旷工(次)', DataType::TYPE_STRING);

            $worksheet->mergeCells('L2:L3');
            $worksheet->setCellValueExplicit('L2', '补卡(次)', DataType::TYPE_STRING);

            $worksheet->mergeCells('M2:N2');
            $worksheet->setCellValueExplicit('M2', '迟到(次)', DataType::TYPE_STRING);

            $worksheet->mergeCells('O2:P2');
            $worksheet->setCellValueExplicit('O2', '早退(次)', DataType::TYPE_STRING);

            $worksheet->mergeCells('Q2:X2');
            $worksheet->setCellValueExplicit('Q2', '请假(天)', DataType::TYPE_STRING);
            $worksheet->getStyle('A2:X3')->applyFromArray([  //将A1-T1内的字设置为水平居中
                'alignment' => [
                    'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
                ]
            ]);
            $startRow = 3;
            foreach ($dataSource as $key => $value) {
                $cell = 'A';
                $bCell = '';
                $key += $startRow + 1;
                foreach ($value as $field => $val) {
                    if ($cell > 'Z') {
                        if ($bCell == '') {
                            $bCell = 'A';
                        } else {
                            $bCell++;
                        }
                        $cell = 'A';
                    }
                    $worksheet->setCellValueExplicit($bCell . $cell . $key, $val, DataType::TYPE_STRING)
                        ->getStyle($bCell . $cell . $key)->getAlignment()->setWrapText(true);
                    if ($field == 'sStaffName' && strpos($val, '离职') !== false) {
                        $worksheet->getStyle('A'.$key.':X'.$key)
                            ->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_RED);
                    }
                    $cell++;
                }
            }
            //导出代码
            $worksheet->setTitle($xmlName);
            $fileName = $xmlName.'.xlsx';
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment;filename="'.$fileName.'"');
            header('Cache-Control: max-age=0');
            $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
            $writer->save('php://output');
        } catch (\Exception $e) {
            return $this->sendErrorResponse(500, $e->getMessage());
        }
    }

    /**
     * 导入职工详情
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181119
     */
    public function importStaffDetailAction()
    {
        try {
            ini_set('memory_limit', '500M');
            $file = $this->request->getUploadedFiles()[0];
            $fileName = md5_file($file->getTempName()) . '.' . $file->getExtension();
            $filePath = TEMP_PATH . '/' . $fileName;
            $file->moveTo($filePath);
            $dataSource = Tool::readExcelBySheet($filePath, true, 1);
//            $dataSource = Tool::readExcelBySheet($filePath, true, 0);
            $detailSuccess  = $this->importAttendDetail($dataSource, 'moduleOne');
            return $this->sendSuccessResponse($detailSuccess);
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 延时列表
     *
     * @return \Phalcon\Mvc\View
     *
     * create by dale  20181123
     */
    public function overTimeListAction()
    {
        if (!Power::exist('Hrm_Attend')) {
            return $this->sendViewError('缺少权限');
        }
        $startTime = $this->request->getQuery('startTime', 'string', '');
        $endTime = $this->request->getQuery('endTime', 'string', '');
        Assets::easyUI();
        $this->view->setTemplateBefore('listForm');
        Assets::importJs('js/attendance/overTimeList.js');
//        $this->view->pick('attendance/overTimeList');
        Template::exists('Attend_OverTime', 'list') or die(Main::showMessageModal('配置文件不存在，请先创建！', 109106002));
        $listButtonArr = $formButtonArr = $listSearchArr = array();
//            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_importRec', 'text' => '导入',
//                'icon' => 'fa-plus');
//            $listButtonArr[] = array('plain' => 'true', 'id' => 'bt_list_generate', 'text' => '生成每日考勤',
//                'icon' => 'fa-plus');
        $listSearchArr[] = array('type' => 'text', 'class'  => 'easyui-datebox', 'id' => 'List_Search_StartTime',
            'label' => ' 时间段：','style'=>'width:100px;','value' => $startTime);
        $listSearchArr[] = array('type' => 'text', 'class' => 'easyui-datebox', 'id' => 'List_Search_EndTime',
            'label' => ' ~ ', 'style' => 'width:100px;','value' => $endTime);
        $listSearchArr[] = array('type' => 'text', 'id' => 'list_search', 'label' => ' 搜索： ');
        $listSearchArr[] = array('type' => 'button', 'id' => 'bt_list_search', 'text' => '查找',
            'icon' => 'fa-search', 'style' => 'margin-left:10px');
        $listSearchArr[] = array('type' => 'button', 'id' => 'excel_export', 'text' => '导出',
            'icon' => 'fa fa-file-excel-o');
        return $this->view->setVars(array(
            'List' => Template::createList('overList', 'Attend_OverTime', [
                'searchToolbar' => Template::createSearchToolBar($listSearchArr, !!$listButtonArr),
                'buttonToolbar' => Template::createButtonToolBar($listButtonArr),
            ]),
        ));
    }

    /**
     * 获取加班数据
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181123
     * modify by dale 20181211
     */
    public function getOverTimeAction()
    {
        try {
            if (!Power::exist('Hrm_Attend')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $startTime = $this->request->getPost('startTime', 'string');
            $endTime = $this->request->getPost('endTime', 'string');
            $key = $this->request->getPost('key', 'string');
            $depTag = $this->request->getPost('depTag', 'string');
            $builder = $this->modelsManager->createBuilder()
                ->columns('a.sStaffNumber,a.sStaffName')
                ->from(['a' => 'Admin\Models\hrm\XhhrmAttend'])
                ->where('a.bDelete = 0')
                ->groupBy('a.sStaffNumber');
            if ($startTime) {
                $builder->andWhere('sDay >= :startTime:', ['startTime' => $startTime]);
            }
            if ($endTime) {
                $builder->andWhere('sDay <= :endTime:', ['endTime' => $endTime]);
            }
            if ($key) {
                $builder->andWhere('sStaffName like :key: or sStaffNumber like :key:', ['key' => '%'.$key.'%']);
            }
            if ($depTag) {
                $depTree = array_column(self::$depTree, null, 'depTag');
                $depInfo = Tool::getValue($depTree, $depTag);
                if ($depInfo && $depInfo['prefixRange']) {
                    $strArr = [];
                    foreach ($depInfo['prefixRange'] as $index => $row) {
                        $strArr[] = " a.sStaffNumber like  '%{$row}%' ";
                    }
                    $builder->andWhere(implode('or', $strArr));
                }
            }
            $data = Main::runBuilderPage($builder);
            $staffNumberArr = array_column($data['rows'], 'sStaffNumber');
            if (!$staffNumberArr) {
                return $this->sendJsonResponse(['rows' => [], 'total' => 0]);
            }
            $attendDailyBuilder = $builder = $this->modelsManager->createBuilder()
                ->columns('sStaffNumber,sDay,dOverTime,iMeal,dOverWeek,iOffType,dOffDay')
                ->from('Admin\Models\hrm\XhhrmAttend')
                ->where(
                    'bDelete= 0 and sStaffNumber in ({ids:array}) and (iMeal > 0 or iOffType != 0)',
                    ['ids' => $staffNumberArr]
                );
            if ($startTime) {
                $attendDailyBuilder->andWhere('sDay >= :startTime:', ['startTime' => $startTime]);
            }
            if ($endTime) {
                $attendDailyBuilder->andWhere('sDay <= :endTime:', ['endTime' => $endTime]);
            }
            $attendDailyArr = $attendDailyBuilder->getQuery()->execute()->toArray();
            $sortedArr = [];
            foreach ($attendDailyArr as $index => $row) {
                $sortedArr[$row['sStaffNumber']][] = $row;
                unset($attendDailyArr[$index]);
            }
            foreach ($data['rows'] as $index => &$row) {
                $row['overWeek'] = []; //周末加班
                $row['overWork'] = []; //延时加班
                $row['overHalfWeek'] = []; //延时加班
                $row['overHalfWork'] = []; //延时加班
                $row['halfOffDay'] = [];
                $row['offDay'] = [];
                $arr = Tool::getValue($sortedArr, $row['sStaffNumber'], []);
                if ($arr) {
                    foreach ($arr as $content) {
                        $day = date("m-d", strtotime($content['sDay']));
                        if ($content['dOverTime'] > 0) {
                            $content['dOverTime'] = floatval($content['dOverTime']);
                            if ($content['dOverTime'] == 1) {
                                $row['overWork'][] = $day;
                            } elseif ($content['dOverTime'] == 0.5) {
                                $row['overHalfWork'][] = $day;
                            }
                        }
                        if ($content['dOverWeek'] > 0) {
                            $content['dOverWeek'] = floatval($content['dOverWeek']);
                            if ($content['dOverWeek'] == 1) {
                                $row['overWeek'][] = $day;
                            } elseif ($content['dOverWeek'] == 0.5) {
                                $row['overHalfWeek'][] = $day;
                            }
                            //$row['overWeek'] .= $content['sDay'].'周末加班'.floatval($content['dOverWeek']) .'天;'.PHP_EOL;
                        }
                        if ($content['dOffDay'] > 0) {
                            $content['dOffDay'] = floatval($content['dOffDay']);
                            if ($content['iOffType'] == 5 && $content['dOffDay'] == 0.5) { //调休半天
                                $row['halfOffDay'][] = $day;
                            }
                            if ($content['iOffType'] == 5 && $content['dOffDay'] == 1) { //调休一天
                                $row['offDay'][] = $day;
                            }
                        }

                    }
                }
               // var_dump($row);die;
                $row['overWork'] = $this->circulateStr($row['overWork']);
                $row['overWeek'] = $this->circulateStr($row['overWeek']);
                $row['overHalfWeek'] = $this->circulateStr($row['overHalfWeek']);
                $row['overHalfWork'] = $this->circulateStr($row['overHalfWork']);
                $row['halfOffDay'] = $this->circulateStr($row['halfOffDay']);
                $row['offDay'] = $this->circulateStr($row['offDay']);
            }
            return $this->sendJsonResponse($data);
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 导出加班统计
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181123
     */
    public function exportOverWorkAction()
    {
        try {
            if (!Power::exist('Hrm_Attend')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $this->view->disable();
            $startTime = $this->request->getQuery('startTime', 'string');
            $endTime = $this->request->getQuery('endTime', 'string');
            $key = $this->request->getQuery('key', 'string');
            $depTag = $this->request->getQuery('depTag', 'string');
            if (!$startTime || !$endTime) {
                return $this->sendErrorResponse(400, '缺少开始或结束时间');
            }
            $builder = $this->modelsManager->createBuilder()
                ->columns('a.sStaffNumber,a.sStaffName')
                ->from(['a' => 'Admin\Models\hrm\XhhrmAttend'])
                ->where("a.bDelete = 0 and sStaffName <> '' ")
                ->groupBy('a.sStaffNumber');
            if ($startTime) {
                $builder->andWhere('sDay >= :startTime:', ['startTime' => $startTime]);
            }
            if ($endTime) {
                $builder->andWhere('sDay <= :endTime:', ['endTime' => $endTime]);
            }
            if ($key) {
                $builder->andWhere('sStaffName like :key: or sStaffNumber like :key:', ['key' => '%'.$key.'%']);
            }
            if ($depTag) {
                $depTree = array_column(self::$depTree, null, 'depTag');
                $depInfo = Tool::getValue($depTree, $depTag);
                if ($depInfo && $depInfo['prefixRange']) {
                    $strArr = [];
                    foreach ($depInfo['prefixRange'] as $index => $row) {
                        $strArr[] = " a.sStaffNumber like  '%{$row}%' ";
                    }
                    $builder->andWhere(implode('or', $strArr));
                }
            }
            $data = $builder->getQuery()->execute()->toArray();
            $staffNumberArr = array_column($data, 'sStaffNumber');
            if (!$staffNumberArr) {
                return $this->sendErrorResponse(400, '空信息无法导出');
            }
            $attendDailyBuilder = $builder = $this->modelsManager->createBuilder()
                ->columns('sStaffNumber,sDay,dOverTime,iMeal,dOverWeek,iOffType,dOffDay')
                ->from('Admin\Models\hrm\XhhrmAttend')
                ->where(
                    'bDelete= 0 and sStaffNumber in ({ids:array}) and (iMeal > 0 or iOffType != 0)',
                    ['ids' => $staffNumberArr]
                );
            if ($startTime) {
                $attendDailyBuilder->andWhere('sDay >= :startTime:', ['startTime' => $startTime]);
            }
            if ($endTime) {
                $attendDailyBuilder->andWhere('sDay <= :endTime:', ['endTime' => $endTime]);
            }
            $attendDailyArr = $attendDailyBuilder->getQuery()->execute()->toArray();
            $sortedArr = [];
            foreach ($attendDailyArr as $index => $row) {
                $sortedArr[$row['sStaffNumber']][] = $row;
                unset($attendDailyArr[$index]);
            }
            foreach ($data as $index => &$row) {
                $row['overWeek'] = []; //周末加班
                $row['overWork'] = []; //延时加班
                $row['overHalfWeek'] = [];
                $row['overHalfWork'] = [];
                $row['halfOffDay'] = [];
                $row['offDay'] = [];
                $arr = Tool::getValue($sortedArr, $row['sStaffNumber'], []);
                if ($arr) {
                    foreach ($arr as $content) {
                        $day = date("m-d", strtotime($content['sDay']));
                        if ($content['dOverTime'] > 0) {
                            $content['dOverTime'] = floatval($content['dOverTime']);
                            if ($content['dOverTime'] == 1) {
                                $row['overWork'] []= $day;
                            } elseif ($content['dOverTime'] == 0.5) {
                                $row['overHalfWork'] [] = $day;
                            }
                        }
                        if ($content['dOverWeek'] > 0) {
                            $content['dOverWeek'] = floatval($content['dOverWeek']);
                            if ($content['dOverWeek'] == 1) {
                                $row['overWeek'] []= $day;
                            } elseif ($content['dOverWeek'] == 0.5) {
                                $row['overHalfWeek'] [] = $day;
                            }
                        }
                        if ($content['dOffDay'] > 0) {
                            $content['dOffDay'] = floatval($content['dOffDay']);
                            if ($content['iOffType'] == 5 && $content['dOffDay'] == 0.5) { //调休半天
                                $row['halfOffDay'][] = $day;
                            }
                            if ($content['iOffType'] == 5 && $content['dOffDay'] == 1) { //调休一天
                                $row['offDay'][] = $day;
                            }
                        }
                    }
                }
                $row['overWork'] = $this->circulateStr($row['overWork']);
                $row['overWeek'] = $this->circulateStr($row['overWeek']);
                $row['overHalfWeek'] = $this->circulateStr($row['overHalfWeek']);
                $row['overHalfWork'] = $this->circulateStr($row['overHalfWork']);
                $row['halfOffDay'] = $this->circulateStr($row['halfOffDay']);
                $row['offDay'] = $this->circulateStr($row['offDay']);
            }
            unset($row); //解除数据引用
            //数据处理完毕
            $titleArr = [
                'sStaffName' => '职工名称',
                'overHalfWork' => '延时加班一次',
                'overWork' => '延时加班两次',
                'overWeek' => '周末',
                'overHalfWeek' => '周末半天',
                'halfOffDay'   => '调休半天',
                'offDay'       => '调休一天',
            ];
            $dataSource = [];
            foreach ($data as $key => $examine) {
                $row = [];
                foreach ($titleArr as $filed => $name) {
                    $row[$filed] = Tool::getValue($examine, $filed);
                }
                $dataSource[] = $row;
            }
            unset($data);
            $xmlName = "考勤加班统计{$startTime}至{$endTime}";
            $spreadsheet = new Spreadsheet();
            $worksheet = $spreadsheet->getActiveSheet();
            $worksheet->getColumnDimension('A')->setWidth(12);
            $worksheet->getColumnDimension('B')->setWidth(38);
            $worksheet->getColumnDimension('C')->setWidth(38);
            $worksheet->getColumnDimension('D')->setWidth(38);
            $worksheet->getColumnDimension('E')->setWidth(38);
            $worksheet->getColumnDimension('F')->setWidth(38);
            $worksheet->getColumnDimension('G')->setWidth(38);
            $cell = 1;
            foreach ($titleArr as $key => $title) {
                $worksheet->setCellValueByColumnAndRow($cell, 1, is_array($title) ? $title['name'] : $title);
                $cell++;
            }
            $startRow = 1;
            foreach ($dataSource as $key => $value) {
                $cell = 'A';
                $bCell = '';
                $key += $startRow + 1;
                foreach ($value as $field => $val) {
                    if ($cell > 'Z') {
                        if ($bCell == '') {
                            $bCell = 'A';
                        } else {
                            $bCell++;
                        }
                        $cell = 'A';
                    }
                    $worksheet->setCellValueExplicit($bCell . $cell . $key, $val, DataType::TYPE_STRING)
                        ->getStyle($bCell . $cell . $key)->getAlignment()->setWrapText(true);
                    $cell++;
                }
            }
            //导出代码
            $worksheet->setTitle($xmlName);
            $fileName = $xmlName.'.xlsx';
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment;filename="'.$fileName.'"');
            header('Cache-Control: max-age=0');
            $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
            $writer->save('php://output');
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }


    /**
     * 计算长度
     *
     * @param $arr
     *
     * @return string
     *
     * create by dale  20181124
     */
    public function circulateStr($arr)
    {
        if (!$arr) {
            return '';
        }
        $num = 0;
        $str = '';
        $endValue = end($arr);
        foreach ($arr as $row) {
            $str .= $row ;
            if ($row != $endValue) {
                $str .= '、';
            }
            $num++;
            if ($num == 5) {
                $num = 0;
                $str .= PHP_EOL;
            }
        }
        return $str;
    }

    /**
     * 获取请假类型
     *
     * @param $weekStart
     * @param $weekEnd
     * @param $titleWeekArr
     * @param $row
     *
     * @return int|mixed
     *
     * create by dale  20181121
     */
    public function getWeekType($weekStart, $weekEnd, $titleWeekArr, $row)
    {
        $type = 0;
        $enums = self::$enums['iOffType'];
        $valueIndex = 0;
        for ($i = $weekStart; $i <= $weekEnd; $i++) { //获取到有值的
            if ($row[$i]) {
                $valueIndex = $i;
                break;
            }
        }
        if ($valueIndex) {
            $name = Tool::getValue($titleWeekArr, $valueIndex, '');
            foreach ($enums as $index => $field) {
                if ($field) {
                    if (strpos($name, $field) !== false) {
                        $type = $index;
                    }
                }
            }
        }
        return $type;
    }

    /**
     * 获取星级
     *
     * @param $lateType
     * @param $earType
     * @param $dWeek
     * @param $dOver
     *
     * @return string
     *
     * create by dale  20181116
     */
    public function checkStr($lateType, $earType, $dWeek, $dOver)
    {
        $str = '<i class="fa fa-star" aria-hidden="true" style="color:#00ee00"></i>';
        if (in_array($lateType, [1, 2]) || in_array($earType, [1, 2])) {
            $str = '<i class="fa fa-star" aria-hidden="true" style="color:yellow"></i>';
        }
        if ($lateType == 3 || $earType == 3) {
            $str = '<i class="fa fa-star" aria-hidden="true" style="color: red"></i>';
        }
        if (floatval($dWeek) > 0 || floatval($dOver) > 0) {
            $str = '<i class="fa fa-star" aria-hidden="true" style="color: #00aced"></i>';
        }
        return $str;
    }

    /**
     * 设置假期
     *
     * @return \Phalcon\Mvc\View|string
     *
     * create by dale  20181123
     */
    public function setHolidayAction()
    {
        try {
            $this->view->pick('attendance/setHoliday');
            Assets::FullCalendar();
            Assets::importJs('js/attendance/setHoliday.js');
            return $this->view->setVars([]);
        } catch (\Exception $e) {
            return $this->sendViewError(
                $e->getMessage()
            );
        }
    }

    /**
     * 获取假期
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181126
     */
    public function getHolidayAction()
    {
        try {
            $startDay = $this->request->getPost('startDay', 'string');
            $endDay = $this->request->getPost('endDay', 'string');
            if (!$startDay ||  !$endDay) {
                return $this->sendErrorResponse(400, '缺少参数');
            }
            if ($startDay > $endDay) {
                return $this->sendErrorResponse(400, '开始时间');
            }
            $setArr = XhhrmHoliday::find([
                'conditions' => 'bDelete= 0 and sDay >= :startDay: and sDay <= :endDay:',
                'bind'       => ['startDay' => $startDay, 'endDay' => $endDay],
            ])->toArray();
            if ($setArr) {
                $setArr = array_column($setArr, null, 'sDay');
            }
            $arr = [];
            for ($day = $startDay; $day <= $endDay; $day = date('Y-m-d', strtotime("$day +1 day"))) {
                $setDay = Tool::getValue($setArr, $day);
                if ($setDay) {
                    $item = [
                        'id'    => $setDay['iSHId'],
                        'start' => $day,
                        'title' => $setDay['bHoliday'] ? '休息日' : '工作日',
                        'isHoliday' => $setDay['bHoliday'],
                        'formDay' => $startDay,
                        'toDay' => $endDay,
                        'backgroundColor' => $setDay['bHoliday'] ? '#86bf69' : '#3a87ad',
                    ];
                    if ($setDay['sDesc']) {
                        $item['title'] .= PHP_EOL.$setDay['sDesc'];
                    }
                } else {
                    $w = date('w', strtotime($day)) + 1;
                    $bHoliday = in_array($w, [1, 7]);
                    $item = [
                        'start' => $day,
                        'title' => $bHoliday ? '休息日' : '工作日',
                        'isHoliday' => $bHoliday ? 1 : 0,
                        'formDay' => $startDay,
                        'toDay' => $endDay,
                        'backgroundColor' => $bHoliday ?  '#86bf69' : '#3a87ad',
                    ];
                }
                $arr[] = $item;
            }
            return $this->sendJsonResponse($arr);
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 保存假期设置
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181126
     */
    public function saveHolidayAction()
    {
        try {
            $this->db->begin();
            $dateType = $this->request->getPost('dayType', 'string'); // 1.工作日 2.假期
            $day = $this->request->getPost('day', 'string');
            $desc = $this->request->getPost('desc', 'string');
            $signType = $this->request->getPost('signType', 'string', 'inSign');
            if (!$day || !$dateType) {
                return $this->sendErrorResponse(400, '缺少参数');
            }
            $w = date('w', strtotime($day)) + 1;
            $bHoliday = in_array($w, [1, 7]);
            $obj = XhhrmHoliday::findFirst([
                'conditions' => 'bDelete= 0 and sDay = :day:',
                'bind'       => ['day' => $day]
            ]);
            if ($dateType == 1 && $bHoliday) { //周末设置为工作日
                if (!$obj) {
                    $obj = new XhhrmHoliday();
                }

            } elseif ($dateType == 2 && !$bHoliday) { //工作日设置为假期
                if (!$obj) {
                    $obj = new XhhrmHoliday();
                }
            } else {
                if ($obj) {
                    if (!$obj->delete()) {
                        $this->db->rollback();
                        return $this->sendErrorResponse(500, '保存失败');
                    }
                }
                $str = $this->changeDayType($day, $dateType, $signType);
                $this->db->commit();
                return $this->sendSuccessResponse('设置成功'.PHP_EOL.$str);
            }
            $obj->sDay = $day;
            $obj->bHoliday = $dateType - 1;
            $obj->sDesc = $desc;
            if (!$obj->save()) {
                $this->db->rollback();
                return $this->sendErrorResponse(500, '保存失败');
            }
            $str = $this->changeDayType($day, $dateType, $signType);
            $this->db->commit();
            return $this->sendSuccessResponse('设置成功'.PHP_EOL.$str);
        } catch (\Exception $e) {
            $this->db->rollback();
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

    /**
     * 修改日期是否休息
     *
     * @param $day
     * @param $dayType
     *
     * @return bool|string
     *
     * create by dale  20181126
     * modify by dale 20190122  添加假期不计计算打卡
     */
    private function changeDayType($day, $dayType, $signType)
    {
//        var_dump($day,$dayType);die;
        if (!Power::exist('Hrm_AttendDetail_Edit')) {
            return $this->sendErrorResponse(403, '缺少权限');
        }
        $attendArr = XhhrmAttend::find([
            'columns'    => 'sStaffNumber,sDay,sStaffName',
            'conditions' => 'bDelete = 0 and sDay = :sDay: ',
            'bind'       => ['sDay' => $day]
        ])->toArray();
        if (!$attendArr) {
            return '没有考勤记录，无需执行考勤修改';
        }
        $totalNum = count($attendArr);
        $successNum = 0;
        $errorNum = 0;
        $errorStr = '';
        if ($dayType == 2 && $signType == 'outSign') { //假期并且不计算打卡
            $objs = XhhrmAttend::find([
                'conditions' => 'bDelete = 0 and sDay = :sDay: ',
                'bind'       => ['sDay' => $day]
            ]);
            foreach ($objs as $obj) {
                try {
                    $obj->assign($this->clearAttendData());
                    $obj->bHoliday = 1;
                    if (!$obj->save()) {
                        throw new XhException('保存失败');
                    }
                    $successNum++;
                } catch (XhException $e) {
                    $errorNum++;
                    $errorStr .= "{$obj->sStaffNumber}在{$obj->sDay}的记录更新失败;";
                    continue;
                }
            }
        } else {
            foreach ($attendArr as $attend) {
                try {
                    $this->getUserAttend($attend['sDay'], $attend['sStaffNumber'], $dayType);
                    $successNum++;
                } catch (XhException $e) {
                    $errorNum++;
                    $errorStr .= "{$attend['sStaffNumber']}在{$attend['sDay']}的记录更新失败;";
                    continue;
                }
            }
        }

        if ($errorNum || $errorStr) {
            $this->createCommitLog($errorStr);
        }
        return "考勤更新成功，共执行{$totalNum}次,成功{$successNum}次，失败{$errorNum}次";
    }


    /**
     * 标记为正常
     *
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface
     *
     * create by dale  20181213
     */
    public function signNormalAction()
    {
        try {
            if (!Power::exist('Hrm_AttendDetail_Edit')) {
                return $this->sendErrorResponse(403, '缺少权限');
            }
            $id = $this->request->getPost('iSAId', 'string');
            if (!$id) {
                return $this->sendErrorResponse(400, '缺少参数');
            }
            $obj = XhhrmAttend::findFirst($id);
            if (!$obj) {
                return $this->sendErrorResponse(400, '未找到数据');
            }
            if (!$obj->bUnusual) {
                return $this->sendErrorResponse(400, '正常记录无需标记为正常');
            }
            $obj->bUnusual = 0;
            if (!$obj->save()) {
                return $this->sendErrorResponse(500, '保存失败');
            }
            return $this->sendSuccessResponse('保存成功');
        } catch (\Exception $e) {
            return $this->sendErrorResponse(
                500,
                $e->getMessage(),
                $e instanceof XhException ? $e->getDescription() : $e->getTrace()
            );
        }
    }

//    public function testAction()
//    {
//        return json_encode([
//            'moduleOne' => 'XHJSB',
//            'moduleTwo' => 'XHJXB',
//            'default'   => 'moduleOne'
//        ]);
//    }



//    public function runAttendAction()
//    {
//        $objArr = XhhrmAttend::find([
//            'conditions' => 'bDelete = 0 '
//        ]);
////        var_dump($objArr->toArray());die;
//        foreach ($objArr as $obj) {
//            $arr = $this->calculateOverTime(
//                $obj->sDay,
//                $obj->sSignIn,
//                $obj->sSignOut,
//                $obj->bHoliday ? true: false,
//                $obj->sCheckInfo
//            );
//            $obj->assign($arr);
//            if (!$obj->save()) {
//                return $this->sendErrorResponse(500, '保存失败');
//            }
//        }
//        return $this->sendSuccessResponse('执行成功');
//    }

//    public function testAction()
//    {
//        var_dump(strpos());die;
//    }






}